Динамический тип вопроса
Динамический тип вопроса позволяет определять тип поля и виджет во время выполнения на основе ответа API или вычисленного значения.
Функция Динамический тип вопроса позволяет определять виджет ввода и поведение валидации поля во время выполнения, а не при проектировании формы. Это расширенное расширение rtSurvey, используемое, когда тип собираемых данных зависит от серверной конфигурации, ответа API или предшествующего значения поля.
Распространённый сценарий использования — настраиваемый контрольный список инспекций, где сервер определяет, какие поля обязательны, какой тип они имеют (текст, целое число, выбор и т.д.) и какие варианты доступны — без пересборки формы для каждой конфигурации.
Принцип работы
Поле, помеченное как динамический тип вопроса, использует callapi() для получения конфигурации из API. Ответ API определяет:
- Тип виджета для отображения (text, integer, select_one и т.д.)
- Доступные варианты (для типов выбора)
- Правила валидации
Поле помечается внутренним атрибутом specialFeature: isDynamicQuestionType, который сообщает движку формы использовать ответ API для создания виджета, а не статическое определение формы.
Настройка
Шаг 1: Получение конфигурации поля
Используйте поле calculate с callapi() для получения динамической конфигурации:
| type | name | label | appearance | calculation |
|---|---|---|---|---|
| calculate | field_config | callapi | callapi('POST', 'https://api.example.com/field-config', 1, 2, 0, '$.config', 10000, 0, '', '', '{"form_id": "##form_id##", "field_id": "inspection_result"}') |
Шаг 2: Ссылка на конфигурацию в динамическом поле
Динамическое поле использует callapi-verify() в appearance или constraint для связи с полученной конфигурацией:
| type | name | label | appearance |
|---|---|---|---|
| text | inspection_result | Результат инспекции | callapi-verify(dynamicParams) |
Движок формы считывает field_config и динамически определяет, отображать ли inspection_result как text, integer или select_one.
Формат ответа API
API должен возвращать JSON-объект, описывающий конфигурацию поля. Типичный ответ:
{
"config": {
"type": "select_one",
"choices": [
{"value": "pass", "label": "Пройдено"},
{"value": "fail", "label": "Не пройдено"},
{"value": "na", "label": "Н/П"}
],
"required": true,
"constraint": ". != ''"
}
}
Пример: Настраиваемая форма инспекции
Форма инспекции, где элементы контрольного списка и типы ответов загружаются с сервера в зависимости от категории инспекции:
| type | name | label | appearance | calculation |
|---|---|---|---|---|
| select_one inspection_type | insp_type | Тип инспекции | ||
| calculate | checklist_config | callapi | callapi('POST', 'https://api.example.com/checklist', 1, 2, 0, '$.items', 10000, 0, '', '', '{"type": "##insp_type##"}') | |
| text | item_1 | Пункт 1 | callapi-verify(dynamicParams) | |
| text | item_2 | Пункт 2 | callapi-verify(dynamicParams) | |
| text | item_3 | Пункт 3 | callapi-verify(dynamicParams) |
Сервер возвращает правильный тип виджета, метку, варианты и валидацию для каждого пункта на основе insp_type.
Лучшие практики
- Используйте динамические типы вопросов только тогда, когда структура поля действительно меняется во время выполнения — для статических форм используйте стандартные типы вопросов.
- Убедитесь, что API конфигурации отвечает быстро (менее 2 секунд) и доступен в полевой сети.
- Всегда определяйте разумный запасной вариант в форме на случай недоступности API — обычное поле
textс заметкой лучше, чем сломанный виджет. - Версионируйте схему ответа API — изменения в формате ответа затронут все активные формы, использующие эту конечную точку.
- Тестируйте все комбинации типов полей, которые API может возвращать, перед развёртыванием.
Ограничения
- Динамические типы вопросов требуют сетевого соединения для получения конфигурации.
- Полный диапазон типов виджетов, доступных динамически, зависит от версии клиента rtSurvey — тестируйте целевую версию.
- Это расширенное расширение rtSurvey без аналога в стандартной спецификации XLSForm.
- Отладка ошибок сложнее, поскольку определение поля частично находится в форме и частично в ответе API.