Skip to content

Commit

Permalink
Load values order from JSON based on depends on property fix #8624 (#…
Browse files Browse the repository at this point in the history
…8626)

* Load values order from JSON based on depends on property fix #8624

* Small refactoring #8624
  • Loading branch information
andrewtelnov authored Jul 29, 2024
1 parent 5639ef6 commit 8f3a287
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 21 deletions.
54 changes: 34 additions & 20 deletions src/jsonobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ export class JsonObjectProperty implements IObject, IJsonPropertyInfo {
this.idValue = JsonObjectProperty.Index++;
}
uniqueProperty?: string;
dependsOn?: string | string[];
dependsOn?: string | Array<string>;
default?: any;
defaultFunc?: (obj: Base) => any;
public get id(): number {
Expand Down Expand Up @@ -1028,12 +1028,10 @@ export class JsonMetadataClass {
return prop;
}
private addDependsOnProperties(prop: JsonObjectProperty, dependsOn: any) {
if (Array.isArray(dependsOn)) {
for (var i = 0; i < dependsOn.length; i++) {
this.addDependsOnProperty(prop, dependsOn[i]);
}
} else {
this.addDependsOnProperty(prop, dependsOn);
const dArray = Array.isArray(dependsOn) ? dependsOn : [dependsOn];
prop.dependsOn = dArray;
for (var i = 0; i < dArray.length; i++) {
this.addDependsOnProperty(prop, dArray[i]);
}
}
private addDependsOnProperty(prop: JsonObjectProperty, dependsOn: string) {
Expand Down Expand Up @@ -1689,26 +1687,42 @@ export class JsonObject {
}
properties = this.addDynamicProperties(obj, jsonObj, properties);
this.options = options;
const processedProps: any = {};
processedProps[JsonObject.typePropertyName] = true;
const parentProps = {};
for (var key in jsonObj) {
if (key === JsonObject.typePropertyName) continue;
if (key === JsonObject.positionPropertyName) {
obj[key] = jsonObj[key];
continue;
}
var property = this.findProperty(properties, key);
if (!property) {
if (needAddErrors) {
this.addNewError(new JsonUnknownPropertyError(key.toString(), objType), jsonObj, obj);
}
continue;
}
this.valueToObj(jsonObj[key], obj, property, jsonObj, options);
this.setPropertyValueToObj(jsonObj, obj, key, properties, processedProps, parentProps, objType, needAddErrors, options);
}
this.options = undefined;
if (obj.endLoadingFromJson) {
obj.endLoadingFromJson();
}
}
private setPropertyValueToObj(jsonObj: any, obj: any, key: string, properties: Array<JsonObjectProperty>, processedProps: any, parentProps: any,
objType: string, needAddErrors: boolean, options: ILoadFromJSONOptions): void {
if (processedProps[key]) return;
if (key === JsonObject.positionPropertyName) {
obj[key] = jsonObj[key];
return;
}
const property = this.findProperty(properties, key);
if (!property && needAddErrors) {
this.addNewError(new JsonUnknownPropertyError(key.toString(), objType), jsonObj, obj);
}
if(property) {
const dProps = property.dependsOn;
if(Array.isArray(dProps)) {
parentProps[key] = true;
dProps.forEach(propKey => {
if(!parentProps[propKey]) {
this.setPropertyValueToObj(jsonObj, obj, propKey, properties, processedProps, parentProps, objType, needAddErrors, options);
}
});
}
this.valueToObj(jsonObj[key], obj, property, jsonObj, options);
processedProps[key] = true;
}
}
public toJsonObjectCore(
obj: any,
property: JsonObjectProperty,
Expand Down
2 changes: 1 addition & 1 deletion src/question_text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ Serializer.addClass(
name: "maskSettings:masksettings",
className: "masksettings",
visibleIndex: 1,
dependsOn: "inputType",
dependsOn: ["inputType", "maskType"],
visibleIf: (obj: any) => {
return obj.inputType === "text" || obj.inputType === "tel";
},
Expand Down
16 changes: 16 additions & 0 deletions tests/jsonobjecttests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3308,3 +3308,19 @@ QUnit.test("enableIf", function (assert) {
Serializer.removeProperty("question", "testProperty3");
Serializer.removeProperty("question", "testProperty4");
});
QUnit.test("circular dependsOn, #8624", function (assert) {
const prop1 = Serializer.addProperty("question", { name: "testProperty1" });
Serializer.addProperty("question", { name: "testProperty2", dependsOn: "testProperty1" });
prop1.dependsOn = ["testProperty2"];

const q: any = new Question("q1");
q.fromJSON({
testProperty1: "abc",
testProperty2: "edf"
});
assert.equal(q.testProperty1, "abc", "testProperty1 value");
assert.equal(q.testProperty2, "edf", "testProperty2 value");

Serializer.removeProperty("question", "testProperty1");
Serializer.removeProperty("question", "testProperty2");
});
20 changes: 20 additions & 0 deletions tests/question_texttests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SurveyModel } from "../src/survey";
import { QuestionTextBase, CharacterCounter } from "../src/question_textbase";
import { settings } from "../src/settings";
import { StylesManager } from "../src/stylesmanager";
import { InputMaskPattern } from "../src/mask/mask_pattern";

QUnit.test("check text disabled class", function (assert) {
var json = {
Expand Down Expand Up @@ -488,3 +489,22 @@ QUnit.test("inputType='date' invalid value, #8617", function(assert) {
q1.value = "2000-01-01";
assert.equal(q1.errors.length, 0, "errors #5");
});
QUnit.test("Mask is removed on loading, Bug#8624", function(assert) {
const survey = new SurveyModel({
elements: [
{
maskSettings: {
pattern: "999-99-999999",
saveMaskedValue: true,
},
maskType: "pattern",
name: "q1",
type: "text"
},
]
});
const q1 = <QuestionTextModel>survey.getQuestionByName("q1");
const maskSettings = q1.maskSettings as InputMaskPattern;
assert.equal(q1.maskType, "pattern", "mask type is set correctly");
assert.equal(maskSettings.pattern, "999-99-999999", "pattern is loaded");
});

0 comments on commit 8f3a287

Please sign in to comment.