Search code examples
javascripttypescriptsurveyjs

SurveyJS: Read and set initial value of custom property


I'm developing a custom property to be used in the property grid. The goal of the property is to allow users to select from a dropdown which "attribute" they want to link to a question.

This attribute is a part of the project's business domain and some SurveyJS properties can be automatically set based on the attribute selection. In short: the business domain model aims to impose some structure on the survey builder for domain validation etc.

One of the SurveyJS properties influenced by the attribute is the JSON property the question's answer will be serialised to (valueName), this is how it's currently being set:

import { SurveyModel } from 'survey-core';

let choicesOptions : string[] = [];

export function setDomainAttributeChoices(choices: string[] ){
    choicesOptions = choices;
}

export const domainAttributeProperty = {
    name: 'DomainAttributeProperty',
    category: 'general',
    choices: loadChoices,
    visibleIndex: 0,
    onSetValue: onSetValue
}

function loadChoices(obj: unknown, cb: Function) {
    cb(choicesOptions);
}

function onSetValue(survey: SurveyModel, value: string): void {
    survey.setPropertyValue('valueName', value);
}

Ignore how the choices are being loaded, this is done in this way because the custom SurveyJS widgets, expressions and attributes we're developing are part of a shared library.

The above works as expected, meaning that when I select an option from the dropdown, the valueName property is set accordingly and completing the survey will result in a JSON using the property names based on the attribute selection.

However, I would like to fix the following scenario (this happens in the Survey Builder):

  1. I select a question and change the DomainAttribute property
  2. I deselect that question
  3. I select it again, the custom property does not automatically reselect the value in the dropdown

I would like to be able to, either on focus of the question or on loading of the choices, read the question's valueName property and use this to select the correct value in the choices list, but I cannot find documentation on whether or not this would be possible.

Many thanks for anyone who could point me in the right direction.


Solution

  • I figured out it was related to the fact I am serializing the custom property not as DomainAttributeProperty in the question JSON but as valueName.

    So I made following changes:

    1. On load of choices, read the valueName property of the question and assign it to DomainAttributeProperty. This will make sure the correct choice is selected when refocusing a question.

    2. Mark the custom property as not serializable to avoid having DomainAttributeProperty show up in the JSON.

    This is the final version:

    import { Question } from 'survey-core';
    
    let choicesOptions : string[] = [];
    
    export function setDomainAttributeChoices(choices: string[] ){
        choicesOptions = choices;
    }
    
    export const domainAttributeProperty = {
        name: 'DomainAttributeProperty',
        category: 'general',
        choices: loadChoices,
        visibleIndex: 0,
        onSetValue: onSetValue
    }
    
    function loadChoices(question: Question, cb: Function) {
        const valueName = question.getPropertyValue('valueName');
        questionModel.setPropertyValue('DomainAttributeProperty', valueName);
        cb(choicesOptions);
    }
    
    function onSetValue(question: Question, value: string): void {
        question.setPropertyValue('valueName', value);
    }