Динамический поиск (также называемый 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_pathJSONPath к массиву результирующих объектов в ответе (например, $.data, $.hits.hits.*._source)
save_pathИмя, под которым сохраняется необработанный ответ для использования другими полями

Базовый пример

Поиск медицинского учреждения, когда перечислитель вводит часть его названия:

typenamelabelappearance
select_onefacilityВыберите медицинское учреждение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():

typenamelabelcalculation
select_onefacilityВыберите учреждениеsearch-api(..., 'facility_data')
calculatefacility_districtpulldata('facility_data', 'district')
calculatefacility_typepulldata('facility_data', 'type')

Лучшие практики

  1. Убедитесь, что ваша конечная точка API отвечает в течение 1–2 секунд — медленные API делают поиск неотзывчивым.
  2. Используйте %__input__% в post_body, чтобы API возвращал только совпадающие результаты, а не весь набор данных.
  3. Индексируйте поле поиска на стороне сервера (например, Elasticsearch, полнотекстовый индекс базы данных) для быстрого ответа.
  4. Ограничивайте результаты 20–50 элементами на запрос — возврат тысяч результатов нивелирует смысл поиска.
  5. Требуйте минимальной длины ввода в API, чтобы избежать широких запросов при вводе одного символа.

Ограничения

  • Динамический поиск требует сетевого соединения — не работает в офлайн-режиме.
  • Заполнитель %__input__% подставляется как есть; очищайте входные данные на стороне сервера для предотвращения инъекций.
  • Сложные выражения отображения @{func} могут иметь ограниченную поддержку в разных версиях клиента rtSurvey.
Была ли эта страница полезной?