survey-creator icon indicating copy to clipboard operation
survey-creator copied to clipboard

Allow to create a custom survey serialization

Open rcoady70 opened this issue 3 years ago • 12 comments

Allow to create an alternative serilization for survey. It is needed, when SurveyJS Creator is used to create the JSON form definition that can be used later to generate UI form based on non SurveyJS widgets, for example, for a desktop platform.

A new callback has been added into Serializer: Serializer.onSerializingProperty = (obj: Base, prop: JsonObjectProperty, value: any, json: any): boolean.

Here is the example of using it.

  const mapping : any = {
    base: { elements: "Questions", visible: { name: "IsHidden", converter: (obj: Base, value: any): any => { return !value; } } },
    question: { choices: "AnswerOptions" },
    survey: { title: "Name", pages: "sections" }
  };
  const getMappedObj = function(type: string, name: string): string {
    const typeMap = mapping[type];
    return !!typeMap ? typeMap[name] : undefined;
  };
  Serializer.onSerializingProperty = (obj: Base, prop: JsonObjectProperty, value: any, json: any): boolean => {
    let typesList = new Array<string>();
    typesList.push(obj.getType());
    if(obj.isDescendantOf("question")) {
      typesList.push("question");
    }
    typesList.push("base");

    for(var i = 0; i < typesList.length; i ++) {
      let mapObj = <any>getMappedObj(typesList[i], prop.name);
      if(!mapObj) continue;
      const name = typeof mapObj === "string" ? mapObj : mapObj.name;
      if(typeof mapObj !== "string" && mapObj.converter) {
        value = mapObj.converter(obj, value);
      }
      json[name] = value;
      return true;
    }
    return false;
  };

Original Question

I would like to change the format of the json outputted by the survey creator. Is this possible.

Thanks for your help.

rcoady70 avatar Aug 31 '22 16:08 rcoady70

@rcoady70 It depends on what you are trying to do. You can always modify JSON manually. Anyway, to help you, we need to understand your goal.

Thank you, Andrew

andrewtelnov avatar Sep 01 '22 07:09 andrewtelnov

Thanks Andrew, we taking the json being created by SurveyJs creator and then we run it through another program to convert it to another format. This is then used by an internal system. Ideally we would like to skip the manual middle strep.

SurveyJs Json ---> Convert to our format ---> Consume on internal system.

rcoady70 avatar Sep 01 '22 07:09 rcoady70

@rcoady70 Your scenario is to create survey/form using SurveyJS Creator and then render it using another engine. Is it correct? In this case, could you please provide an example of your JSON? I will try to find a solution.

Thank you, Andrew

andrewtelnov avatar Sep 01 '22 17:09 andrewtelnov

Thanks Andrew, you are correct we have our own runner so need to convert the JSON to our specific format. The JSON is radically different so I was just wondering if there was an easy way to plug in a different json output from SurveyJS

rcoady70 avatar Sep 02 '22 08:09 rcoady70

@rcoady70 If you provide couple examples: Original JSON - result JSON. I would look. It is easy to write two Unit tests and see could I fix them or not. I will have a flight on Sunday. I can play with this task on the plane. I could not promised anything of course.

andrewtelnov avatar Sep 02 '22 08:09 andrewtelnov

Thanks Andrew, I appreciate it. But the formats are so different It would really be a task we would need to take on ourselves mapping would not be at all obvious. I was just wondering if there was an easy hook where we could plug in. We can always look at an external converter.

rcoady70 avatar Sep 02 '22 09:09 rcoady70

I was going to make a hook in our Serializer. It is better to have a real example instead of an abstract task.

Thank you, Andrew

andrewtelnov avatar Sep 02 '22 09:09 andrewtelnov

Understood, please do not waste to much time as we would probably need a method to convert our format back to surveyjs format to allow editing again so a second hook. Before

{ "logoPosition": "right", "pages": [ { "name": "page1", "elements": [ { "type": "radiogroup", "name": "question1", "title": { "default": "This is my first radio question EN ", "da": "This is my first radio question DK", "es": "This is my first radio question ES" }, "choices": [ { "value": "Q1.1", "text": { "default": "item1 EN", "da": "item1 DK", "es": "item1 ES" } }, { "value": "Q1.2", "text": { "default": "item2 EN", "da": "item2 DK", "es": "item2 ES" } }, { "value": "Q1.3", "text": { "default": "Item3 EN", "da": "Item3 DK", "es": "Item3 ES" } } ], "otherText": { "default": "Other (comment) EN", "da": "Other (comment) DK", "es": "Other (comment) ES" } }, { "type": "radiogroup", "name": "question2", "visibleIf": "{question1} = 'Q1.1' or {question1} = 'Q1.2'", "choices": [ { "value": "Q2.1", "visibleIf": "{question1} = 'Q1.1'" }, "Q2.2", "Q2.3" ] } ], "title": { "default": "Survey Page 1 EN", "da": "Survey page 1 DK", "es": "Survey page 1 ES" }, "description": { "default": "First page EN", "da": "First page DK", "es": "First page ES" } } ] }

After

{ "logoPosition": "right", "Name": "Your Questionnaire", "sections": [ { "name": "Section 1", "Questions": [ { "type": "radiogroup", "name": "question1", "title": { "default": "This is my first radio question EN ", "da": "This is my first radio question DK", "es": "This is my first radio question ES", "IsHidden": false, "Required": true, "DisplayConditions": null }, "AnswerOptions": [ { "value": "Q1.1", "text": { "default": "item1 EN", "da": "item1 DK", "es": "item1 ES" } }, { "value": "Q1.2", "text": { "default": "item2 EN", "da": "item2 DK", "es": "item2 ES" } }, { "value": "Q1.3", "text": { "default": "Item3 EN", "da": "Item3 DK", "es": "Item3 ES" } } ], "otherText": { "default": "Other (comment) EN", "da": "Other (comment) DK", "es": "Other (comment) ES" } }, { "type": "radiogroup", "name": "question2", "visibleIf": "{question1} = 'Q1.1' or {question1} = 'Q1.2'", "IsHidden": false, "Required": true, "DisplayConditions": null "AnswerOptions": [ { "value": "Q2.1", "visibleIf": "{question1} = 'Q1.1'" }, "Q2.2", "Q2.3" ] } ], "title": { "default": "Survey Page 1 EN", "da": "Survey page 1 DK", "es": "Survey page 1 ES" }, "description": { "default": "First page EN", "da": "First page DK", "es": "First page ES" } } ] }

rcoady70 avatar Sep 02 '22 10:09 rcoady70

Thanks Andrew, Understood, please do not waste to much time as we would probably need a method to convert our format back to surveyjs format to allow editing again so a second hook. I have created a simple before and after not our format but gives a before and after. Before

{ "logoPosition": "right", "pages": [ { "name": "page1", "elements": [ { "type": "radiogroup", "name": "question1", "title": { "default": "This is my first radio question EN ", "da": "This is my first radio question DK", "es": "This is my first radio question ES" }, "choices": [ { "value": "Q1.1", "text": { "default": "item1 EN", "da": "item1 DK", "es": "item1 ES" } }, { "value": "Q1.2", "text": { "default": "item2 EN", "da": "item2 DK", "es": "item2 ES" } }, { "value": "Q1.3", "text": { "default": "Item3 EN", "da": "Item3 DK", "es": "Item3 ES" } } ], "otherText": { "default": "Other (comment) EN", "da": "Other (comment) DK", "es": "Other (comment) ES" } }, { "type": "radiogroup", "name": "question2", "visibleIf": "{question1} = 'Q1.1' or {question1} = 'Q1.2'", "choices": [ { "value": "Q2.1", "visibleIf": "{question1} = 'Q1.1'" }, "Q2.2", "Q2.3" ] } ], "title": { "default": "Survey Page 1 EN", "da": "Survey page 1 DK", "es": "Survey page 1 ES" }, "description": { "default": "First page EN", "da": "First page DK", "es": "First page ES" } } ] }

After

{ "logoPosition": "right", "Name": "Your Questionnaire", "sections": [ { "name": "Section 1", "Questions": [ { "type": "radiogroup", "name": "question1", "title": { "default": "This is my first radio question EN ", "da": "This is my first radio question DK", "es": "This is my first radio question ES", "IsHidden": false, "Required": true, "DisplayConditions": null }, "AnswerOptions": [ { "value": "Q1.1", "text": { "default": "item1 EN", "da": "item1 DK", "es": "item1 ES" } }, { "value": "Q1.2", "text": { "default": "item2 EN", "da": "item2 DK", "es": "item2 ES" } }, { "value": "Q1.3", "text": { "default": "Item3 EN", "da": "Item3 DK", "es": "Item3 ES" } } ], "otherText": { "default": "Other (comment) EN", "da": "Other (comment) DK", "es": "Other (comment) ES" } }, { "type": "radiogroup", "name": "question2", "visibleIf": "{question1} = 'Q1.1' or {question1} = 'Q1.2'", "IsHidden": false, "Required": true, "DisplayConditions": null "AnswerOptions": [ { "value": "Q2.1", "visibleIf": "{question1} = 'Q1.1'" }, "Q2.2", "Q2.3" ] } ], "title": { "default": "Survey Page 1 EN", "da": "Survey page 1 DK", "es": "Survey page 1 ES" }, "description": { "default": "First page EN", "da": "First page DK", "es": "First page ES" } } ] }

rcoady70 avatar Sep 02 '22 10:09 rcoady70

Thank you! I will be back on next week.

andrewtelnov avatar Sep 02 '22 11:09 andrewtelnov

@rcoady70 Here is my PR. I have decide to do it early. I have updated your original issue title and description.

Thank you, Andrew

andrewtelnov avatar Sep 03 '22 13:09 andrewtelnov

Thanks Andrew, that is very helpful.

On Sat, 3 Sept 2022, 14:02 Andrew, @.***> wrote:

@rcoady70 https://github.com/rcoady70 Here is my PR https://github.com/surveyjs/survey-library/pull/4795. I have decide to do it early. I have updated your original issue title and description.

Thank you, Andrew

— Reply to this email directly, view it on GitHub https://github.com/surveyjs/survey-creator/issues/3395#issuecomment-1236116141, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQGZOIIFUXLTOTQPWKKHIVTV4ND6RANCNFSM6AAAAAAQBQXBTY . You are receiving this because you were mentioned.Message ID: @.***>

rcoady70 avatar Sep 05 '22 07:09 rcoady70