surveyjs / survey-creator

Scalable open-source survey software to generate dynamic JSON-driven forms within your JavaScript application. The form builder features a drag-and-drop UI, CSS Theme Editor, and GUI for conditional logic and form branching.
https://surveyjs.io/open-source
Other
898 stars 373 forks source link

[V1 & V2] Complex default values #2500

Open SamMousa opened 2 years ago

SamMousa commented 2 years ago

Are you requesting a feature, reporting a bug or ask a question?

Bug

What is the current behavior?

Complex default values for custom array properties are not loaded properly.

What is the expected behavior?

The default value should support complex values.

How would you reproduce the current behavior (if this is a bug)?

I'm adding a color dictionary allowing a user to map values to colors.

Survey.Serializer.addClass("coloritemvalue", [
        {
            name: "text",
            visible: false,
        },
        {
            name: "color",
            type: "color"
        },
    ], null, "itemvalue");
    Survey.Serializer.addProperty("survey", {
        category: "Reporting & Dashboarding",
        default: [
            {
                value: "A1",
                color: "#ff0000"
            },
            {
                value: "A2",
                color: "#00ff00"
            }

        ],
        isLocalizable: false,
        // onSetValue: (obj, value, jsonConverter) => {
        //     debugger;
        //     // obj.setPropertyValue("colors", value);
        // },

        type: "coloritemvalue[]",
        name: "colors",
        displayName: "Color Dictionary",

    });

This works if I don't specify a default value, but if I do it gets mangled and the initial JSON shows like this:

{
 "logoPosition": "right",
 "pages": [
  {
   "name": "page1"
  }
 ],
 "colors": [
  "A1",
  "A2"
 ]
}

I think this is caused by the ItemValue default value loader: https://github.com/surveyjs/survey-library/blob/master/src/itemvalue.ts#L433

Specify your

andrewtelnov commented 2 years ago

@SamMousa I was there is a bug in the library. However, there is an issue in your code. I had to look at ticket early. Here is the correct code:

// Create a correct ItemValue, tells that the type is coloritemvalue.
Survey.Serializer.addClass("coloritemvalue", [
        {
            name: "text",
            visible: false,
        },
        {
            name: "color",
            type: "color"
        },
    ], (value) => new Survey.ItemValue(value, "", "coloritemvalue"), "itemvalue");
   //You need to set default objects, to create items with the correct type
   //And set className
    const colorItem1 = new Survey.ItemValue("A1", "", "coloritemvalue");
    colorItem1.color = "#ff0000";
    const colorItem2 = new Survey.ItemValue("A2", "", "coloritemvalue");
    colorItem2.color = "#00ff00";
    Survey.Serializer.addProperty("survey", {
        category: "Reporting & Dashboarding",
        default: [colorItem1, colorItem2],
        isLocalizable: false,
        type: "coloritemvalue[]",
        name: "colors",
        className: "coloritemvalue",
        displayName: "Color Dictionary",

    });

Here is the working example.

Thank you, Andrew

SamMousa commented 2 years ago

But why doesn't the raw JSON go through the same initializing code as if it were loaded from a survey JSON?

andrewtelnov commented 2 years ago

It knows what object it should create. Default value simply set the value directly. It can do some magic internally and create array of ItemValues in Base class, but it doesn't set the correct type.

Thank you, Andrew

SamMousa commented 2 years ago

I tried your solution, but with that code the creator always serializes the value to JSON, even if it is the default value.