Skip to content

Commit

Permalink
onFocusInQuestion doesn't contain information about which particular …
Browse files Browse the repository at this point in the history
…matrix cell was focused fix #6698 (#6788)
  • Loading branch information
andrewtelnov committed Aug 25, 2023
1 parent 0d183fb commit ae5efae
Show file tree
Hide file tree
Showing 20 changed files with 125 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<ng-template #template>
<td [class]="cell.className" [attr.data-responsive-title]="getHeaders()" [title]="cell.getTitle()"
[style]="getCellStyle()" [attr.colspan]="cell.colSpans" #cellContainer>
[style]="getCellStyle()" [attr.colspan]="cell.colSpans" (focusin)="cell.focusIn()" #cellContainer>
<sv-ng-matrix-drag-drop-icon *ngIf="cell.isDragHandlerCell"
[model]="$any({ data: { row: row, question: question } })"></sv-ng-matrix-drag-drop-icon>
<sv-action-bar *ngIf="cell.isActionsCell" [model]="cell.item.getData()" [handleClick]="false"></sv-action-bar>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
>{{ model.editor.requiredText }}</span
>
</span>
<div [class]="question.getItemCss()">
<div [class]="question.getItemCss()" (focusin)="model.focusIn()">
<div *ngIf="model.editor.showErrorOnTop && model.editor.hasVisibleErrors" [element]="model.editor" sv-ng-errors></div>
<sv-ng-text-question [model]="model.editor"></sv-ng-text-question>
<div *ngIf="model.editor.showErrorOnBottom && model.editor.hasVisibleErrors" [element]="model.editor" sv-ng-errors></div>
Expand Down
1 change: 1 addition & 0 deletions packages/survey-vue3-ui/src/MatrixCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:title="cell.getTitle()"
:style="(getCellStyle() as StyleValue)"
:colspan="cell.colSpans"
v-on:focusin="cell.focusIn()"
ref="root"
>
<survey-errors v-if="cell.isErrorsCell" :element="cell.question" />
Expand Down
6 changes: 5 additions & 1 deletion packages/survey-vue3-ui/src/MultipletextItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
>{{ item.editor.requiredText }}</span
>
</span>
<div :key="item.editor.id" :class="question.getItemCss()">
<div
:key="item.editor.id"
:class="question.getItemCss()"
v-on:focusin="item.focusIn()"
>
<survey-errors
v-if="item.editor.showErrorOnTop"
:element="item.editor"
Expand Down
2 changes: 1 addition & 1 deletion src/knockout/templates/question-matrixdynamic.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
</script>
<script type="text/html" id="survey-matrixcell">
<td
data-bind="css: $data.className, style: { minWidth: $data.minWidth, width: $data.width }, attr: { 'data-responsive-title': headers, title: $data.getTitle(), colspan: $data.colSpans }"
data-bind="css: $data.className, style: { minWidth: $data.minWidth, width: $data.width }, attr: { 'data-responsive-title': headers, title: $data.getTitle(), colspan: $data.colSpans }, event: {focusin: $data.focusIn }"
>
<div data-bind="visible: question.isVisible, css: $parentContext.question.cssClasses.cellQuestionWrapper">
<!-- ko if: $data.isOtherChoice -->
Expand Down
2 changes: 1 addition & 1 deletion src/knockout/templates/question-multipletext.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<span data-bind="css: question.koItemTitleCss">
<!-- ko component: { name: 'survey-element-title-content', params: {element: item.editor} } --><!-- /ko -->
</span>
<div data-bind="css: question.koItemCss">
<div data-bind="css: question.koItemCss, event: {focusin: item.focusIn }">
<!-- ko if: item.editor.showErrorOnTop -->
<!-- ko template: { name: 'survey-question-errors', data: item.editor } -->
<!-- /ko -->
Expand Down
2 changes: 1 addition & 1 deletion src/knockout/templates/questioncontent.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script type="text/html" id="survey-question-content">
<div data-bind="visible: !question.isCollapsed, css: question.cssContent" role="presentation">
<div data-bind="visible: !question.isCollapsed, css: question.cssContent, event: {focusin: question.focusIn }" role="presentation">
<!-- ko if: question.showErrorOnTop -->
<!-- ko template: { name: 'survey-question-errors', data: question } -->
<!-- /ko -->
Expand Down
2 changes: 1 addition & 1 deletion src/knockout/templates/row.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</script>
<script type="text/html" id="survey-row-content">
<!-- ko foreach: { data: row.visibleElements, as: 'question', afterRender: row.koAfterRender } -->
<div data-bind="css: question.cssClasses.questionWrapper, style: $data.rootStyle, event: {focusin: question.focusIn }">
<div data-bind="css: question.cssClasses.questionWrapper, style: $data.rootStyle">
<!-- ko if: row.isNeedRender -->
<!-- ko component: { name: row.panel.survey.getElementWrapperComponentName(question), params: { componentData: row.panel.survey.getElementWrapperComponentData(question), templateData: { name: question.koElementType, data: question, afterRender: $parent.koElementAfterRender } } } -->
<!-- /ko -->
Expand Down
3 changes: 2 additions & 1 deletion src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ export class Question extends SurveyElement<Question>
public get isCompositeQuestion(): boolean {
return false;
}
public get isContainer(): boolean { return false; }
protected updateCommentElements(): void {
if(!this.autoGrowComment || !Array.isArray(this.commentElements)) return;
for(let i = 0; i < this.commentElements.length; i ++) {
Expand Down Expand Up @@ -1043,7 +1044,7 @@ export class Question extends SurveyElement<Question>
this.expandAllParents((<any>element).parentQuestion);
}
public focusIn(): void {
if(!this.survey) return;
if(!this.survey || this.isDisposed || this.isContainer) return;
(this.survey as SurveyModel).whenQuestionFocusIn(this);
}
protected fireCallback(callback: () => void): void {
Expand Down
2 changes: 2 additions & 0 deletions src/question_custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,8 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
questions[i].onAnyValueChanged(name);
}
}
public get hasSingleInput(): boolean { return false; }
public get isContainer(): boolean { return true; }
protected createPanel(): PanelModel {
var res = <PanelModel>Serializer.createClass("panel");
res.showQuestionNumbers = "off";
Expand Down
5 changes: 2 additions & 3 deletions src/question_matrixdropdownbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -878,9 +878,8 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
super.dispose();
this.clearGeneratedRows();
}
public get hasSingleInput(): boolean {
return false;
}
public get hasSingleInput(): boolean { return false; }
public get isContainer(): boolean { return true; }
public get isRowsDynamic(): boolean {
return false;
}
Expand Down
5 changes: 5 additions & 0 deletions src/question_matrixdropdownrendered.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ export class QuestionMatrixDropdownRenderedCell {
.append(matrixCssClasses.choiceCell, this.isChoice)
.toString();
}
public focusIn(): void {
if(this.question) {
this.question.focusIn();
}
}
}

export class QuestionMatrixDropdownRenderedRow extends Base {
Expand Down
8 changes: 5 additions & 3 deletions src/question_multipletext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ export class MultipleTextItemModel extends Base
this.editor.setParentQuestion(<any>data);
}
}
public focusIn(): void {
this.editor.focusIn();
}
/**
* Set this property to true, to make the item a required. If a user doesn't fill the item then a validation error will be generated.
*/
Expand Down Expand Up @@ -332,9 +335,8 @@ export class QuestionMultipleTextModel extends Question
public get isAllowTitleLeft(): boolean {
return false;
}
public get hasSingleInput(): boolean {
return false;
}
public get hasSingleInput(): boolean { return false; }
public get isContainer(): boolean { return true; }
public get id() {
return this.getPropertyValue("id");
}
Expand Down
11 changes: 4 additions & 7 deletions src/question_paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ export class QuestionPanelDynamicModel extends Question
});
this.registerPropertyChangedHandlers(["allowAddPanel"], () => { this.updateNoEntriesTextDefaultLoc(); });
}
public get hasSingleInput(): boolean {
return false;
}
public get isCompositeQuestion(): boolean { return true; }
public get hasSingleInput(): boolean { return false; }
public get isContainer(): boolean { return true; }
public getFirstQuestionToFocus(withError: boolean): Question {
for (var i = 0; i < this.visiblePanels.length; i++) {
const res = this.visiblePanels[i].getFirstQuestionToFocus(withError);
Expand Down Expand Up @@ -339,10 +339,7 @@ export class QuestionPanelDynamicModel extends Question
public getType(): string {
return "paneldynamic";
}
public get isCompositeQuestion(): boolean {
return true;
}
public clearOnDeletingContainer() {
public clearOnDeletingContainer(): void {
this.panels.forEach((panel) => {
panel.clearOnDeletingContainer();
});
Expand Down
7 changes: 5 additions & 2 deletions src/react/reactquestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -388,14 +388,17 @@ export class SurveyQuestionAndErrorsCell extends SurveyQuestionAndErrorsWrapped
}
protected renderElement(): JSX.Element {
var style = this.getCellStyle();
const cell = this.props.cell;
const focusIn = () => { cell.focusIn(); };
return (
<td
ref={this.cellRef}
className={this.itemCss}
colSpan={this.props.cell.colSpans}
colSpan={cell.colSpans}
data-responsive-title={this.getHeaderText()}
title={this.props.cell.getTitle()}
title={cell.getTitle()}
style={style}
onFocus={focusIn}
>
{this.wrapCell(this.props.cell,
(
Expand Down
13 changes: 7 additions & 6 deletions src/react/reactquestion_multipletext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ export class SurveyQuestionMultipleText extends SurveyQuestionElementBase {
rowIndex: number,
items: Array<MultipleTextItemModel>,
cssClasses: any
) {
var key: string = "item" + rowIndex;
var tds:Array<JSX.Element> = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
): JSX.Element {
const key: string = "item" + rowIndex;
const tds:Array<JSX.Element> = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
const focusIn = () => { item.focusIn(); };
tds.push(
<td key={"item" + i} className={this.question.cssClasses.cell}>
<td key={"item" + i} className={this.question.cssClasses.cell} onFocus={focusIn}>
<SurveyMultipleTextItem question={this.question} item={item} creator={this.creator} cssClasses={cssClasses}></SurveyMultipleTextItem>
</td>
);
Expand Down
2 changes: 1 addition & 1 deletion src/react/row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class SurveyRow extends SurveyElementBase<any, any> {
const css = (element as Question).cssClassesValue;
const focusIn = () => {
const el: any = element;
if(el && !el.isDisposed && el.isQuestion) {
if(el && el.isQuestion) {
el.focusIn();
}
};
Expand Down
1 change: 1 addition & 0 deletions src/vue/matrixcell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:title="cell.getTitle()"
:style="getCellStyle()"
:colspan="cell.colSpans"
v-on:focusin="cell.focusIn()"
>
<survey-errors
v-if="cell.isErrorsCell"
Expand Down
2 changes: 1 addition & 1 deletion src/vue/multipletextitem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
>{{ item.editor.requiredText }}</span
>
</span>
<div :key="item.editor.id" :class="question.getItemCss()">
<div :key="item.editor.id" :class="question.getItemCss()" v-on:focusin="item.focusIn()">
<survey-errors
v-if="item.editor.showErrorOnTop"
:element="item.editor"
Expand Down
79 changes: 78 additions & 1 deletion testCafe/survey/focusQuestionEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,81 @@ frameworks.forEach(async framework => {
window["survey"].enterKeyAction = "default";
})();
});
});
test("Check question focus event", async t => {
const getVal = ClientFunction(() => {
return window["survey_focusedName"];
});
await initSurvey(framework, {
pages: [
{
elements: [
{
type: "text",
name: "start"
},
{
type: "text",
name: "q1"
},
{
type: "matrixdropdown",
name: "q2",
rows: ["Row1"],
columns: [
{ name: "col1", cellType: "text" },
{ name: "col2", cellType: "text" }
]
},
{
type: "multipletext",
name: "q3",
items: [
{ name: "text1" },
{ name: "text2" }
]
},
{
type: "dropdown",
name: "q4",
choices: ["item1", "item2"]
},
{
type: "checkbox",
name: "q5",
choices: ["item1", "item2"]
},
{
type: "text",
name: "res"
}
]
}
]
});
await ClientFunction(() => {
window["survey_focusedName"] = undefined;
window["survey"].onFocusInQuestion.add(function (sender, options) {
const q = options.question;
let name = q.name;
if(q.parentQuestion) {
name = q.parentQuestion.name + "." + name;
}
window["survey_focusedName"] = name;
});
})();
await t.pressKey("tab")
.expect(getVal()).eql("q1");
await t.pressKey("tab")
.expect(getVal()).eql("q2.col1");
await t.pressKey("tab")
.expect(getVal()).eql("q2.col2");
await t.pressKey("tab")
.expect(getVal()).eql("q3.text1");
await t.pressKey("tab")
.expect(getVal()).eql("q3.text2");
await t.pressKey("tab")
.expect(getVal()).eql("q4");
await t.pressKey("tab")
.expect(getVal()).eql("q5");
});
});

0 comments on commit ae5efae

Please sign in to comment.