Skip to content

Commit

Permalink
Allow to change value format for composite question #6475 (#6476)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov authored Jul 5, 2023
1 parent f09690a commit 252f539
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/question_custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ export interface ICustomQuestionTypeConfiguration {
* @see questionJSON
*/
createQuestion?: any;
valueToQuestion?: (val: any) => any;
valueFromQuestion?: (val: any) => any;
}

export class ComponentQuestionJSON {
Expand Down Expand Up @@ -234,15 +236,15 @@ export class ComponentQuestionJSON {
if (!this.json.onLoaded) return;
this.json.onLoaded(question);
}
public onAfterRender(question: Question, htmlElement: any) {
public onAfterRender(question: Question, htmlElement: any): void {
if (!this.json.onAfterRender) return;
this.json.onAfterRender(question, htmlElement);
}
public onAfterRenderContentElement(
question: Question,
element: Question,
htmlElement: any
) {
): void {
if (!this.json.onAfterRenderContentElement) return;
this.json.onAfterRenderContentElement(question, element, htmlElement);
}
Expand All @@ -254,7 +256,7 @@ export class ComponentQuestionJSON {
question: Question,
propertyName: string,
newValue: any
) {
): void {
if (!this.json.onPropertyChanged) return;
this.json.onPropertyChanged(question, propertyName, newValue);
}
Expand All @@ -272,7 +274,7 @@ export class ComponentQuestionJSON {
propertyName: string,
name: string,
newValue: any
) {
): void {
if (!this.json.onItemValuePropertyChanged) return;
this.json.onItemValuePropertyChanged(question, {
obj: item,
Expand All @@ -285,7 +287,15 @@ export class ComponentQuestionJSON {
if (!this.json.getDisplayValue) return question.getDisplayValue(keyAsText, value);
return (this.json as any).getDisplayValue(question);
}
public get isComposite() {
public valueToQuestion(val: any): any {
if (!this.json.valueToQuestion) return val;
return this.json.valueToQuestion(val);
}
public valueFromQuestion(val: any): any {
if (!this.json.valueFromQuestion) return val;
return this.json.valueFromQuestion(val);
}
public get isComposite(): boolean {
return !!this.json.elementsJSON || !!this.json.createElements;
}
}
Expand Down Expand Up @@ -854,7 +864,7 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
}
super.onSurveyLoad();
if (!!this.contentPanel) {
const val = this.contentPanel.getValue();
const val = this.getContentPanelValue();
if (!Helpers.isValueEmpty(val)) {
this.value = val;
}
Expand Down Expand Up @@ -919,11 +929,18 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
this.settingNewValue = false;
}
private updateValueCoreWithPanelValue(): boolean {
const panelValue = this.contentPanel.getValue();
const panelValue = this.getContentPanelValue();
if(this.isTwoValueEquals(this.getValueCore(), panelValue)) return false;
this.setValueCore(panelValue);
return true;
}
private getContentPanelValue(val?: any): any {
if(!val) val = this.contentPanel.getValue();
return this.customQuestion.valueToQuestion(val);
}
private getValueForContentPanel(val: any): any {
return this.customQuestion.valueFromQuestion(val);
}
private setNewValueIntoQuestion(name: string, newValue: any): void {
var q = this.getQuestionByName(name);
if (!!q && !this.isTwoValueEquals(newValue, q.value)) {
Expand All @@ -933,7 +950,7 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
public addConditionObjectsByContext(
objects: Array<IConditionObject>,
context: any
) {
): void {
if (!this.contentPanel) return;
var questions = this.contentPanel.questions;
var prefixName = this.name;
Expand All @@ -947,24 +964,25 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
}
}
protected convertDataValue(name: string, newValue: any): any {
var val = this.value;
var val = this.getValueForContentPanel(this.value);
if (!val) val = {};
if (this.isValueEmpty(newValue) && !this.isEditingSurveyElement) {
delete val[name];
} else {
val[name] = newValue;
}
return val;
return this.getContentPanelValue(val);
}
protected setQuestionValue(newValue: any, updateIsAnswered: boolean = true): void {
this.setValuesIntoQuestions(newValue);
if (!this.isEditingSurveyElement && !!this.contentPanel) {
newValue = this.contentPanel.getValue();
newValue = this.getContentPanelValue();
}
super.setQuestionValue(newValue, updateIsAnswered);
}
private setValuesIntoQuestions(newValue: any): void {
if(!this.contentPanel) return;
newValue = this.getValueForContentPanel(newValue);
const oldSettingNewValue = this.settingNewValue;
this.settingNewValue = true;
const questions = this.contentPanel.questions;
Expand Down
84 changes: 84 additions & 0 deletions tests/question_customtests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2211,5 +2211,89 @@ QUnit.test("Composite & onValueChanged", function (assert) {
assert.equal(onValueChangedCounter, 1 + 1); //+ runCondition to chagne the value
assert.deepEqual(survey.data, { q1: { backcolor: "#ffffff", hovercolor: "#f8f8f8", corner: 4, cornerRadius: "4px", border: "0 1 2 rgba(0, 0, 0, 0.15)" } });

ComponentCollection.Instance.clear();
});
QUnit.test("Composite & valueToQuestion/valueFromQuestion, #6475", function (assert) {
ComponentCollection.Instance.add({
name: "elementsettings",
showInToolbox: false,
elementsJSON: [
{
type: "text",
name: "item1"
},
{
type: "text",
name: "item2"
}
],
valueToQuestion(val: any): any {
if(!val) return "";
let res = !!val.item1 ? val.item1 : "";
res += ",";
res += !!val.item2 ? val.item2 : "";
return res;
},
valueFromQuestion(val: any): any {
if(!val) return {};
const res = val.split(",");
if(res.length < 2) res.push("");
return { item1: res[0], item2: res[1] };
}
});
ComponentCollection.Instance.add({
name: "rootquestion",
showInToolbox: false,
elementsJSON: [
{
type: "elementsettings",
name: "settings"
}
]
});
const survey = new SurveyModel({
elements: [
{ type: "elementsettings", name: "q1" },
{ type: "rootquestion", name: "q2" }
] });
const q1 = <QuestionCompositeModel>survey.getQuestionByName("q1");
const qItem1 = q1.contentPanel.getQuestionByName("item1");
const qItem2 = q1.contentPanel.getQuestionByName("item2");
qItem1.value = "val1";
qItem2.value = "val2";
assert.equal(qItem1.value, "val1", "item1 question value is correct, #1");
assert.equal(qItem2.value, "val2", "item2 question value is correct, #1");
assert.equal(q1.value, "val1,val2", "composite question value is correct, #1");
assert.deepEqual(survey.data, { q1: "val1,val2" }, "survey data is correct, #1");
q1.value = "val3,val4";
assert.equal(qItem1.value, "val3", "item1 question value is correct, #2");
assert.equal(qItem2.value, "val4", "item2 question value is correct, #2");
assert.equal(q1.value, "val3,val4", "composite question value is correct, #2");
assert.deepEqual(survey.data, { q1: "val3,val4" }, "survey data is correct, #2");

const q2 = <QuestionCompositeModel>survey.getQuestionByName("q2");
const q2Settings = <QuestionCompositeModel>(q2.contentPanel.getQuestionByName("settings"));
const q2SettingsItem1 = q2Settings.contentPanel.getQuestionByName("item1");
const q2SettingsItem2 = q2Settings.contentPanel.getQuestionByName("item2");
q2SettingsItem1.value = "val5";
q2SettingsItem2.value = "val6";
assert.equal(q2SettingsItem1.value, "val5", "item1 question value is correct, #3");
assert.equal(q2SettingsItem2.value, "val6", "item2 question value is correct, #3");
assert.equal(q2Settings.value, "val5,val6", "composite question value is correct, #3");
assert.deepEqual(q2.value, { settings: "val5,val6" }, "composite root question value is correct, #3");
assert.deepEqual(survey.data, { q1: "val3,val4", q2: { settings: "val5,val6" } }, "survey data is correct, #3");
q2Settings.value = "val7,val8";
assert.equal(q2SettingsItem1.value, "val7", "item1 question value is correct, #4");
assert.equal(q2SettingsItem2.value, "val8", "item2 question value is correct, #4");
assert.equal(q2Settings.value, "val7,val8", "composite question value is correct, #4");
assert.deepEqual(q2.value, { settings: "val7,val8" }, "composite root question value is correct, #4");
assert.deepEqual(survey.data, { q1: "val3,val4", q2: { settings: "val7,val8" } }, "survey data is correct, #4");
q2.value = { settings: "val9,val10" };
assert.equal(q2SettingsItem1.value, "val9", "item1 question value is correct, #5");
assert.equal(q2SettingsItem2.value, "val10", "item2 question value is correct, #5");
assert.equal(q2Settings.value, "val9,val10", "composite question value is correct, #5");
assert.deepEqual(q2.value, { settings: "val9,val10" }, "composite root question value is correct, #5");
assert.deepEqual(survey.data, { q1: "val3,val4", q2: { settings: "val9,val10" } }, "survey data is correct, #5");

ComponentCollection.Instance.clear();
});

0 comments on commit 252f539

Please sign in to comment.