Skip to content

Commit

Permalink
Add survey onElementWrapperComponentName and onElementWrapperComponen…
Browse files Browse the repository at this point in the history
…tData events (#8386)

Co-authored-by: tsv2013 <tsv2013@users.noreply.github.com>
  • Loading branch information
andrewtelnov and tsv2013 authored Jun 9, 2024
1 parent 3842aba commit 38fda0f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 26 deletions.
13 changes: 13 additions & 0 deletions src/survey-events-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1018,4 +1018,17 @@ export interface PopupVisibleChangedEvent extends QuestionEventMixin {
* Indicates whether the popup is visible now.
*/
visible: boolean;
}

export interface ElementWrapperComponentEventMixin {
element: any;
wrapperName: string;
reason?: string;
item?: ItemValue;
}
export interface ElementWrapperComponentNameEvent extends ElementWrapperComponentEventMixin {
componentName: string;
}
export interface ElementWrapperComponentDataEvent extends ElementWrapperComponentEventMixin {
data: any;
}
56 changes: 32 additions & 24 deletions src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ import {
MatrixCellValueChangingEvent, MatrixCellValidateEvent, DynamicPanelModifiedEvent, DynamicPanelRemovingEvent, TimerPanelInfoTextEvent, DynamicPanelItemValueChangedEvent,
DynamicPanelGetTabTitleEvent, DynamicPanelCurrentIndexChangedEvent, IsAnswerCorrectEvent, DragDropAllowEvent, ScrollingElementToTopEvent, GetQuestionTitleActionsEvent,
GetPanelTitleActionsEvent, GetPageTitleActionsEvent, GetPanelFooterActionsEvent, GetMatrixRowActionsEvent, ElementContentVisibilityChangedEvent, GetExpressionDisplayValueEvent,
ServerValidateQuestionsEvent, MultipleTextItemAddedEvent, MatrixColumnAddedEvent, GetQuestionDisplayValueEvent, PopupVisibleChangedEvent, ChoicesSearchEvent, OpenFileChooserEvent
ServerValidateQuestionsEvent, MultipleTextItemAddedEvent, MatrixColumnAddedEvent, GetQuestionDisplayValueEvent, PopupVisibleChangedEvent, ChoicesSearchEvent,
OpenFileChooserEvent, ElementWrapperComponentNameEvent, ElementWrapperComponentDataEvent
} from "./survey-events-api";
import { QuestionMatrixDropdownModelBase } from "./question_matrixdropdownbase";
import { QuestionMatrixDynamicModel } from "./question_matrixdynamic";
Expand Down Expand Up @@ -843,6 +844,8 @@ export class SurveyModel extends SurveyElementCore
*/
public onPopupVisibleChanged: EventBase<SurveyModel, PopupVisibleChangedEvent> = this.addEvent<SurveyModel, PopupVisibleChangedEvent>();

public onElementWrapperComponentName: EventBase<SurveyModel, ElementWrapperComponentNameEvent> = this.addEvent<SurveyModel, ElementWrapperComponentNameEvent>();
public onElementWrapperComponentData: EventBase<SurveyModel, ElementWrapperComponentDataEvent> = this.addEvent<SurveyModel, ElementWrapperComponentDataEvent>();
//#endregion

constructor(jsonObj: any = null, renderedElement: any = null) {
Expand Down Expand Up @@ -7430,7 +7433,7 @@ export class SurveyModel extends SurveyElementCore
this.focusingQuestionInfo = undefined;
}

public questionEditFinishCallback(question: Question, event: any) {
public questionEditFinishCallback(question: Question, event: any): void {
const enterKeyAction = this.enterKeyAction || settings.enterKeyAction;
if (enterKeyAction == "loseFocus") event.target.blur();
if (enterKeyAction == "moveToNextEditor") {
Expand All @@ -7444,40 +7447,45 @@ export class SurveyModel extends SurveyElementCore
}
}
}

private elementWrapperComponentNameCore(componentName: string, element: any, wrapperName: string, reason?: string, item?: ItemValue): string {
if(this.onElementWrapperComponentName.isEmpty) return componentName;
const options = { componentName: componentName, element: element, wrapperName: wrapperName, reason: reason, item: item };
this.onElementWrapperComponentName.fire(this, options);
return options.componentName;
}
private elementWrapperDataCore(data: any, element: any, wrapperName: string, reason?: string, item?: ItemValue): any {
if(this.onElementWrapperComponentData.isEmpty) return data;
const options = { data: data, element: element, wrapperName: wrapperName, reason: reason, item: item };
this.onElementWrapperComponentData.fire(this, options);
return options.data;
}
public getElementWrapperComponentName(element: any, reason?: string): string {
if (reason === "logo-image") {
return "sv-logo-image";
}
return SurveyModel.TemplateRendererComponentName;
const res = reason === "logo-image" ? "sv-logo-image" : SurveyModel.TemplateRendererComponentName;
return this.elementWrapperComponentNameCore(res, element, "component", reason);
}
public getQuestionContentWrapperComponentName(element: any): string {
return SurveyModel.TemplateRendererComponentName;
return this.elementWrapperComponentNameCore(SurveyModel.TemplateRendererComponentName, element, "content-component");
}
public getRowWrapperComponentName(row: QuestionRowModel): string {
return SurveyModel.TemplateRendererComponentName;
return this.elementWrapperComponentNameCore(SurveyModel.TemplateRendererComponentName, row, "row");
}
public getItemValueWrapperComponentName(item: ItemValue, question: QuestionSelectBase): string {
return this.elementWrapperComponentNameCore(SurveyModel.TemplateRendererComponentName, question, "itemvalue", undefined, item);
}
public getElementWrapperComponentData(element: any, reason?: string): any {
return element;
return this.elementWrapperDataCore(element, element, "component", reason);
}
public getRowWrapperComponentData(row: QuestionRowModel): any {
return row;
return this.elementWrapperDataCore(row, row, "row");
}
public getItemValueWrapperComponentName(
item: ItemValue,
question: QuestionSelectBase
): string {
return SurveyModel.TemplateRendererComponentName;
}
public getItemValueWrapperComponentData(
item: ItemValue,
question: QuestionSelectBase
): any {
return item;
public getItemValueWrapperComponentData(item: ItemValue, question: QuestionSelectBase): any {
return this.elementWrapperDataCore(item, question, "itemvalue", undefined, item);
}
public getMatrixCellTemplateData(cell: any) {
return cell.question;
public getMatrixCellTemplateData(cell: any): any {
const res: any = cell.question;
return this.elementWrapperDataCore(res, res, "cell");
}

public searchText(text: string): Array<IFindElement> {
if (!!text) text = text.toLowerCase();
var res: Array<IFindElement> = [];
Expand Down
56 changes: 54 additions & 2 deletions tests/surveytests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Base } from "../src/base";
import { SurveyElement } from "../src/survey-element";
import { SurveyModel } from "../src/survey";
import { PageModel } from "../src/page";
import { PanelModel } from "../src/panel";
import { PanelModel, QuestionRowModel } from "../src/panel";
import { ElementFactory, QuestionFactory } from "../src/questionfactory";
import { Question } from "../src/question";
import { QuestionHtmlModel } from "../src/question_html";
Expand Down Expand Up @@ -14910,7 +14910,59 @@ QUnit.test("getQuestionContentWrapperComponentName", function (assert) {
"default component"
);
});

QUnit.test("onElementWrapperComponentName event", function (assert) {
const survey = new SurveyModel({
elements: [{ type: "text", name: "q1" }, { type: "checkbox", name: "q2", choices: [1, 2] }]
});
const q1 = survey.getQuestionByName("q1");
const q2 = <QuestionCheckboxModel>survey.getQuestionByName("q2");
survey.onElementWrapperComponentName.add((sender, options) => {
if(options.wrapperName === "component" && options.reason === "test1") {
options.componentName += "#1";
}
if(options.wrapperName === "content-component" && options.reason === undefined) {
options.componentName += "#2";
}
if(options.wrapperName === "row" && !!options.element.setIsLazyRendering) {
options.componentName += "#3";
}
if(options.wrapperName === "itemvalue" && options.item?.value === 1) {
options.componentName += "#4";
}
});
assert.equal(survey.getElementWrapperComponentName(q1, "test1"), "sv-template-renderer#1", "#1");
assert.equal(survey.getQuestionContentWrapperComponentName(q1), "sv-template-renderer#2", "#2");
assert.equal(survey.getRowWrapperComponentName(new QuestionRowModel(survey.pages[0])), "sv-template-renderer#3", "#3");
assert.equal(survey.getItemValueWrapperComponentName(q2.choices[0], q2), "sv-template-renderer#4", "#4");
});
QUnit.test("onElementWrapperComponentName event", function (assert) {
const survey = new SurveyModel({
elements: [{ type: "text", name: "q1" }, { type: "checkbox", name: "q2", choices: [1, 2] },
{ type: "matrixdynamic", name: "q3", rowCount: 1, columns: [{ name: "col1" }] }
]
});
const q1 = survey.getQuestionByName("q1");
const q2 = <QuestionCheckboxModel>survey.getQuestionByName("q2");
const q3 = <QuestionMatrixDynamicModel>survey.getQuestionByName("q3");
survey.onElementWrapperComponentData.add((sender, options) => {
if(options.wrapperName === "component" && options.reason === "test1") {
options.data = "#1";
}
if(options.wrapperName === "row" && !!options.element.setIsLazyRendering) {
options.data = "#2";
}
if(options.wrapperName === "itemvalue" && options.item?.value === 1) {
options.data = "#3";
}
if(options.wrapperName === "cell" && options.element.name === "col1") {
options.data = "#4";
}
});
assert.equal(survey.getElementWrapperComponentData(q1, "test1"), "#1", "#1");
assert.equal(survey.getRowWrapperComponentData(new QuestionRowModel(survey.pages[0])), "#2", "#2");
assert.equal(survey.getItemValueWrapperComponentData(q2.choices[0], q2), "#3", "#3");
assert.equal(survey.getMatrixCellTemplateData(q3.visibleRows[0].cells[0]), "#4", "#4");
});
QUnit.test(
"Skip trigger test and auto focus first question on the page",
function (assert) {
Expand Down

0 comments on commit 38fda0f

Please sign in to comment.