Динамический поиск
Динамический поиск загружает варианты из удалённого API в реальном времени по мере набора перечислителем текста, позволяя работать с большими или часто обновляемыми наборами данных.
Динамический поиск (также называемый Search API) позволяет полю select_one, select_multiple или text загружать варианты из удалённого веб-сервиса во время выполнения по мере набора перечислителем текста. Это правильный подход, когда список вариантов слишком велик для включения в CSV-файл, часто обновляется или поступает из живой базы данных.
Внешний вид search-api()
Динамический поиск настраивается через столбец appearance с использованием функции search-api():
search-api(method, url, post_body, value_column, display, data_path, save_path)
Параметры
| Параметр | Описание |
|---|---|
method | Всегда используйте 'POST' |
url | Конечная точка API для запроса |
post_body | Тело JSON, отправляемое в API. Используйте %__input__% как заполнитель для текущего текста поиска перечислителя |
value_column | Ключ в объекте ответа для использования в качестве хранимого значения |
display | Ключ (или шаблон) для использования в качестве метки в выпадающем списке. Поддерживает заполнители ##key## и выражения @{func} |
data_path | JSONPath к массиву результирующих объектов в ответе (например, $.data, $.hits.hits.*._source) |
save_path | Имя, под которым сохраняется необработанный ответ для использования другими полями |
Базовый пример
Поиск медицинского учреждения, когда перечислитель вводит часть его названия:
| type | name | label | appearance |
|---|---|---|---|
| select_one | facility | Выберите медицинское учреждение | search-api('POST', 'https://api.example.com/facilities/search', '{"query": "%__input__%"}', 'id', 'name', '$.results', 'facility_data') |
API получает {"query": "nair"} при вводе перечислителем “nair” и возвращает:
{
"results": [
{"id": "HF001", "name": "Nairobi Central Clinic"},
{"id": "HF002", "name": "Nairobi West Hospital"}
]
}
В выпадающем списке отображаются Nairobi Central Clinic и Nairobi West Hospital; хранимое значение — HF001 или HF002.
Расширенное форматирование отображения
Использование шаблонов ##key##
Отображение нескольких полей в метке:
search-api('POST', 'https://api.example.com/search', '{"q": "%__input__%"}', 'id', '##name## (##district##)', '$.data', 'res')
Отображается как: Nairobi Central Clinic (Найроби).
Использование выражений @{func}
Применение условной логики в метке:
search-api('POST', 'https://api.example.com/search', '{"q": "%__input__%"}', 'id',
'@{if_else(eq("##status##", "active"), "✓ ##name##", "✗ ##name##")}',
'$.data', 'res')
Активные результаты показывают ✓ Название клиники; неактивные — ✗ Название клиники.
Установка значения по умолчанию: search-default-api()
Используйте search-default-api() после search-api() для предзаполнения поля вариантом по умолчанию, загруженным из отдельного API-вызова (например, при редактировании существующей записи):
appearance: search-api(...) search-default-api('POST', 'https://api.example.com/get', '{"id": "##saved_id##"}', 'id', 'name', '$.item')
Пользовательский разделитель для select_multiple: search-default-separator()
Для полей select_multiple укажите, как несколько выбранных значений объединяются в хранимую строку:
appearance: search-api(...) search-default-separator(' || ')
Разделитель по умолчанию — пробел.
Поддерживаемые типы вопросов
| Тип вопроса | Сценарий использования |
|---|---|
select_one | Единственный выбор из результатов поиска |
select_multiple | Множественный выбор из результатов поиска |
text | Автозаполнение — перечислитель вводит свободно, но может выбрать предложение |
Использование сохранённых данных ответа
save_path сохраняет полный объект ответа API под указанным именем. Другие поля могут ссылаться на него через pulldata():
| type | name | label | calculation |
|---|---|---|---|
| select_one | facility | Выберите учреждение | search-api(..., 'facility_data') |
| calculate | facility_district | pulldata('facility_data', 'district') | |
| calculate | facility_type | pulldata('facility_data', 'type') |
Лучшие практики
- Убедитесь, что ваша конечная точка API отвечает в течение 1–2 секунд — медленные API делают поиск неотзывчивым.
- Используйте
%__input__%вpost_body, чтобы API возвращал только совпадающие результаты, а не весь набор данных. - Индексируйте поле поиска на стороне сервера (например, Elasticsearch, полнотекстовый индекс базы данных) для быстрого ответа.
- Ограничивайте результаты 20–50 элементами на запрос — возврат тысяч результатов нивелирует смысл поиска.
- Требуйте минимальной длины ввода в API, чтобы избежать широких запросов при вводе одного символа.
Ограничения
- Динамический поиск требует сетевого соединения — не работает в офлайн-режиме.
- Заполнитель
%__input__%подставляется как есть; очищайте входные данные на стороне сервера для предотвращения инъекций. - Сложные выражения отображения
@{func}могут иметь ограниченную поддержку в разных версиях клиента rtSurvey.