Create Specialized Question Types
Built-in question types are versatile and multi-functional, but in some cases, you need a question type with a more specific functionality. For example, you need to pre-populate a Dropdown with a country list. You can use a regular Dropdown and customize it directly, or you can create a specialized question type. The first approach is more straightforward, but the second results in a more reusable solution. Let's consider both.
The first example pre-populates a standard Dropdown question. You can specify the choices
or choicesByUrl
property (depending on whether the choices come from a server or not). The following code shows a Country question configured in this manner:
{
"name": "country",
"type": "dropdown",
"placeholder": "Select a country...",
"choicesByUrl": {
"url": "https://surveyjs.io/api/CountriesExample"
}
}
If you add this question to the Toolbox in Survey Creator, end users can use it in their surveys. However, this approach has a number of drawbacks:
- End users can edit the
choicesByUrl
property in Property Grid and break the functionality. - If the question needs modifications (for example, if the server URL has changed), end users have to modify every created instance of this question individually.
- In the JSON schema, your custom question looks like a regular Dropdown question.
To avoid these drawbacks, use a different approach: add your custom question type to the survey's ComponentCollection
:
import { ComponentCollection } from "survey-core";
ComponentCollection.Instance.add({
// A unique name for the custom question type; must use lowercase
name: "country",
// A display name used in the Toolbox
title: "Country",
// A default title for questions created with this question type
defaultQuestionTitle: "Country",
// A JSON schema for the base question type (Dropdown in this case)
questionJSON: {
"type": "dropdown",
"placeholder": "Select a country...",
"choicesByUrl": {
"url": "https://surveyjs.io/api/CountriesExample",
}
},
// Inherit all or individual properties from the base question type
inheritBaseProps: true // or [ "allowClear" ]
});
This approach gives you the following advantages:
- In Survey Creator, a corresponding toolbox item appears automatically.
- End users cannot break the functionality because the Property Grid hides the
questionJSON
object properties. If you want to make these properties editable, you can include their names in theinheritBaseProps
array. - If you modify the question configuration, changes automatically apply to every instance of this question.
- A cleaner JSON schema:
{ "type": "country", "name": "question1" }
Localize Specialized Questions
You can localize specialized questions by following the same technique used to localize survey contents. The following code shows how to translate texts within a specialized question to French and German while using English as the default language:
import { ComponentCollection } from "survey-core";
ComponentCollection.Instance.add({
name: "country",
title: {
"default": "Country",
"fr": "Pays",
"de": "Land"
},
defaultQuestionTitle: {
"default": "Country",
"fr": "Pays",
"de": "Land"
},
questionJSON: {
"type": "dropdown",
"placeholder": {
"default": "Select a country...",
"fr": "Sélectionner un pays...",
"de": "Land auswählen..."
},
"choicesByUrl": {
"url": "https://surveyjs.io/api/CountriesExample",
}
},
inheritBaseProps: true
});