Skip to content

Commit

Permalink
The survey.focusFirstQuestionAutomatic / survey.focusFirstQuestion fu…
Browse files Browse the repository at this point in the history
…nction doesn't focus a Dynamic Panel with no input fields fix #8764
  • Loading branch information
andrewtelnov committed Sep 7, 2024
1 parent 67c37bf commit 3d255d5
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<button type="button" *ngIf="question.canAddPanel" [class]="question.getAddButtonCss()" (click)="addPanelClick()">
<button type="button" [id]="question.addButtonId" *ngIf="question.canAddPanel" [class]="question.getAddButtonCss()" (click)="addPanelClick()">
<span [class]="question.cssClasses.buttonAddText"><sv-ng-string [model]="question.locPanelAddText"></sv-ng-string></span>
</button>
14 changes: 11 additions & 3 deletions packages/survey-core/src/question_paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,14 @@ export class QuestionPanelDynamicModel extends Question
const res = this.visiblePanelsCore[i].getFirstQuestionToFocus(withError);
if (!!res) return res;
}
if(this.showAddPanelButton && (!withError || this.currentErrorCount > 0)) return this;
return null;
}

public setSurveyImpl(value: ISurveyImpl, isLight?: boolean) {
protected getFirstInputElementId(): string {
if(this.showAddPanelButton) return this.addButtonId;
return super.getFirstInputElementId();
}
public setSurveyImpl(value: ISurveyImpl, isLight?: boolean): void {
super.setSurveyImpl(value, isLight);
this.setTemplatePanelSurveyImpl();
this.setPanelsSurveyImpl();
Expand Down Expand Up @@ -1075,6 +1079,9 @@ export class QuestionPanelDynamicModel extends Question
public set allowAddPanel(val: boolean) {
this.setPropertyValue("allowAddPanel", val);
}
public get addButtonId(): string {
return this.id + "addPanel";
}
/**
* Specifies the position of newly added panels.
*
Expand Down Expand Up @@ -1789,13 +1796,14 @@ export class QuestionPanelDynamicModel extends Question
}
}
this.updateIsReady();
if (this.isReadOnly || !this.allowAddPanel) {
if (!this.showAddPanelButton) {
this.updateNoEntriesTextDefaultLoc();
}
this.updateFooterActions();
this.isBuildingPanelsFirstTime = false;
this.releaseAnimations();
}
private get showAddPanelButton(): boolean { return this.allowAddPanel && !this.isReadOnly; }
private get wasNotRenderedInSurvey(): boolean {
return !this.hasPanelBuildFirstTime && !this.wasRendered && !!this.survey;
}
Expand Down
21 changes: 20 additions & 1 deletion packages/survey-core/tests/question_paneldynamic_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7380,4 +7380,23 @@ QUnit.test("Always focus on error in duplicated value, Bug8228", function (asser
assert.ok(focusedQuestionId, "Focus on the question");

SurveyElement.FocusElement = oldFunc;
});
});
QUnit.test("getFirstQuestionToFocus, Bug#8764", function (assert) {
const survey = new SurveyModel({
elements: [
{ type: "paneldynamic", name: "panel", panelCount: 1,
templateElements: [{ type: "text", name: "q1" }, { type: "text", name: "q2", isRequired: true }]
}
]
});
const panel = <QuestionPanelDynamicModel>survey.getQuestionByName("panel");
panel.validate(true);
assert.equal(panel.getFirstQuestionToFocus(false).name, "q1", "#1");
assert.equal(panel.getFirstQuestionToFocus(true).name, "q2", "#2");
panel.panelCount = 0;
assert.equal(panel.getFirstQuestionToFocus(false).name, "panel", "#3");
assert.notOk(panel.getFirstQuestionToFocus(true), "#4");
panel.isRequired = true;
panel.validate(true);
assert.equal(panel.getFirstQuestionToFocus(true).name, "panel", "#5");
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class SurveyQuestionPanelDynamicAddButton extends SurveyQuestionPanelDyna
if (!this.question.canAddPanel) return null;
const btnText = this.renderLocString(this.question.locPanelAddText);
return (
<button type="button" className={this.question.getAddButtonCss()} onClick={this.handleClick} >
<button type="button" id={this.question.addButtonId} className={this.question.getAddButtonCss()} onClick={this.handleClick} >
<span className={this.question.cssClasses.buttonAddText}>{btnText}</span>
</button>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<button
type="button"
:id="question.addButtonId"
v-if="question.canAddPanel"
:class="question.getAddButtonCss()"
@click="addPanelClick"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- ko if: question.koCanAddPanel -->
<button type="button" data-bind="click: question.koAddPanelClick, css: question.koAddButtonCss, visible: question.koCanAddPanel">
<button type="button" data-bind="click: question.koAddPanelClick, css: question.koAddButtonCss, visible: question.koCanAddPanel, attr: { id: question.addButtonId }">
<span data-bind="css: question.cssClasses.buttonAddText"><!-- ko template: { name: 'survey-string', data: question.locPanelAddText } --><!-- /ko --></span>
</button>
<!-- /ko -->
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<button
type="button"
:id="question.addButtonId"
v-if="question.canAddPanel"
:class="question.getAddButtonCss()"
@click="addPanelClick"
Expand Down
22 changes: 22 additions & 0 deletions testCafe/questions/paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,5 +578,27 @@ frameworks.forEach((framework) => {

await t.expect(Selector(".sv-action.sv-dots").visible).ok();
});
test("Focus first input on adding a new panel, renderMode='tab'", async (t) => {
await initSurvey(framework, {
focusFirstQuestionAutomatic: true,
elements: [
{
type: "paneldynamic",
name: "panel1",
panelCount: 0,
templateElements: [
{
type: "text",
name: "name"
},
],
}
]
});
await t.pressKey("space")
.pressKey("1 2 3")
.click(Selector(".sd-navigation__complete-btn"));

await t.expect(await getSurveyResult()).eql({ panel1: [{ name: "123" }] });
});
});

0 comments on commit 3d255d5

Please sign in to comment.