Problem
Surveys embedded in a host application depend on values the host injects at runtime via survey.setVariable() and references as {customerTier} in visibleIf, enableIf, defaultValueExpression, calculatedValues. This works when the host renders the survey directly (MIT integration demo) and breaks the moment Creator is involved (Full demo):
- Design time. The condition editor and Logic tab only know questions and calculated values. A variable is not a known name, so the user cannot pick it, sees no type or allowed values, and types
{customerTier} = 'gold' by hand with no validation.
- Preview. Variables cannot be set in the Preview tab. Every condition that depends on one evaluates against
undefined, so Preview represents no real respondent and branching cannot be tested.
Proposal
Developer API
interface ICreatorOptions {
// Ordinary survey JSON, one per application, built by the developer (in Creator if they like).
// Every host variable is a question; variable name = the key the question produces in `data`
// (valueName if set, otherwise name). Type, inputType, min/max, choices, validators, title —
// all read from the question. There is no separate variable schema.
variableDefinition?: any;
// Developer-defined presets; read-only for the Creator user. `variables` is a data record
// of variableDefinition.
variablePresets?: { name: string; variables: any }[];
}
variableDefinition is a survey on purpose: it is rendered as-is to edit a preset in Preview, its validators validate presets, its defaultValues are the implicit preset when none is defined, and its own logic can hide fields that don't apply to a persona. Nothing is re-described anywhere.
Design time
- Condition editor and Logic tab list the definition's questions in a "Variables" group next to survey questions. Selecting one produces
{name}; the value editor is built from the definition question's JSON exactly as it is for survey questions today, so a text/number/min/max variable gets a bounded numeric input, a dropdown gets its choices, a datetime-local gets a date picker.
- Expression editor autocompletion includes variable names.
- Property grid rejects a question name/valueName that collides with a definition variable, the same way it rejects duplicate question names. (Linter counterpart: survey-library#.)
Preview tab
- With more than one preset (developer + user), a preset selector appears in the Preview toolbar. With one preset it is applied silently. With none but a definition, the definition's
defaultValues are applied. With neither, nothing changes from today.
- On run and on preset switch the preview survey is re-created and each key of the active preset is applied via
setVariable() before rendering. Keys absent from the definition are ignored (a stale user preset must not break Preview after a developer renames a variable).
- When
variableDefinition is set, an "Edit variables" action opens a popup rendering the definition with the active preset as data. From it the user can apply values to the current run, or save them as a new named preset; saving runs the definition's validators. Developer presets are not editable in place — the user duplicates and edits the copy.
- The active preset name is remembered per user.
User settings
Introduce ICreatorUserSettings for per-user, per-application, survey-independent state — it cannot live with the survey JSON or the theme, which are per-survey artifacts. Naming follows ICreatorOptions: options are what the developer sets before Creator starts; user settings are what the user changes while using it and expects to find again.
interface ICreatorUserSettings {
variablePresets?: { name: string; variables: any }[]; // user-authored presets
preview?: { variablePreset?: string }; // remembered selection
}
creator.userSettings: ICreatorUserSettings;
creator.saveUserSettingsFunc; // same pattern as saveSurveyFunc / saveThemeFunc
creator.onUserSettingsChanged;
Rules: developer presets from options are never written into user settings; a user preset with the name of a developer preset is rejected on save rather than allowed to shadow it; everything under userSettings must be safe to drop — if the developer never wires saveUserSettingsFunc, Creator behaves exactly as today. The last rule is what stops this object from becoming a second survey-state store.
Relation to the Tester
A preset is a survey start state. The Tester tab picks from the same preset list, and the recorder stores the active preset name on ISurveyTestStart.variablePreset (library side: survey-library#). No second "start from" concept is introduced.
Out of scope for the first iteration
- Editing
variableDefinition inside Creator; the developer owns it and builds it as a separate form.
- Per-survey presets. Variables come from the host application and are shared across all its surveys, so presets are application/user scoped.
- Async or server-fetched variable values in Preview.
Motivation from the integration demo
The Full demo passes fake customer/employee context into surveys built in Creator. Without this, the demo either exposes raw {var} expressions the visitor cannot edit visually, or shows a Preview in which every context-dependent condition is dead. With it, the demo shows the real workflow: the developer wires the variables once, form builders branch on them visually and test each persona in Preview.
Problem
Surveys embedded in a host application depend on values the host injects at runtime via
survey.setVariable()and references as{customerTier}invisibleIf,enableIf,defaultValueExpression,calculatedValues. This works when the host renders the survey directly (MIT integration demo) and breaks the moment Creator is involved (Full demo):{customerTier} = 'gold'by hand with no validation.undefined, so Preview represents no real respondent and branching cannot be tested.Proposal
Developer API
variableDefinitionis a survey on purpose: it is rendered as-is to edit a preset in Preview, its validators validate presets, itsdefaultValues are the implicit preset when none is defined, and its own logic can hide fields that don't apply to a persona. Nothing is re-described anywhere.Design time
{name}; the value editor is built from the definition question's JSON exactly as it is for survey questions today, so atext/number/min/maxvariable gets a bounded numeric input, a dropdown gets its choices, adatetime-localgets a date picker.Preview tab
defaultValues are applied. With neither, nothing changes from today.setVariable()before rendering. Keys absent from the definition are ignored (a stale user preset must not break Preview after a developer renames a variable).variableDefinitionis set, an "Edit variables" action opens a popup rendering the definition with the active preset asdata. From it the user can apply values to the current run, or save them as a new named preset; saving runs the definition's validators. Developer presets are not editable in place — the user duplicates and edits the copy.User settings
Introduce
ICreatorUserSettingsfor per-user, per-application, survey-independent state — it cannot live with the survey JSON or the theme, which are per-survey artifacts. Naming followsICreatorOptions: options are what the developer sets before Creator starts; user settings are what the user changes while using it and expects to find again.Rules: developer presets from
optionsare never written into user settings; a user preset with the name of a developer preset is rejected on save rather than allowed to shadow it; everything underuserSettingsmust be safe to drop — if the developer never wiressaveUserSettingsFunc, Creator behaves exactly as today. The last rule is what stops this object from becoming a second survey-state store.Relation to the Tester
A preset is a survey start state. The Tester tab picks from the same preset list, and the recorder stores the active preset name on
ISurveyTestStart.variablePreset(library side: survey-library#). No second "start from" concept is introduced.Out of scope for the first iteration
variableDefinitioninside Creator; the developer owns it and builds it as a separate form.Motivation from the integration demo
The Full demo passes fake customer/employee context into surveys built in Creator. Without this, the demo either exposes raw
{var}expressions the visitor cannot edit visually, or shows a Preview in which every context-dependent condition is dead. With it, the demo shows the real workflow: the developer wires the variables once, form builders branch on them visually and test each persona in Preview.