При разработке динамических подсказок и интеграции внешних сервисов поиска (например, подсказок по контрагентам или адресам) разработчики часто сталкиваются с нестандартным поведением поля ввода в управляемых формах: при наборе текста или нажатии пробела введенная строка неожиданно очищается, а курсор сбрасывается. Проанализируем, почему возникает такое поведение, какие ограничения накладывает платформа на обработчик АвтоПодбор, и разберем архитектурно правильный способ реализации поиска.
Рассмотрим ключевые факторы, которые приводят к очистке поля ввода или потере введенных символов:
АвтоПодбор категорически запрещено использовать контекстные серверные процедуры и функции. При контекстном вызове состояние всей формы передается на сервер и возвращается обратно на клиент. Это инициирует обновление элементов интерфейса, что сбрасывает текущий буфер редактирования поля ввода. Согласно синтакс-помощнику, вызовы должны быть строго &НаСервереБезКонтекста.СписокВыбора непосредственно в момент набора текста переинициализирует внутренний контекст элемента управления. В результате фокус и введенный текст могут быть сброшены.РежимВыбораИзСписка, платформа пытается немедленно сопоставить введенный текст со значениями списка. Не найдя соответствия при вводе пробела, платформа очищает значение.Для Сч = 0 По ... разработчик вручную выполняет Сч = Сч + 1;. Поскольку управляющая конструкция сама инкрементирует переменную на каждом шаге, шаг цикла удваивается, и ровно половина найденных значений теряется.Выясним, как правильно передавать параметры на сервер. Если функции требуются вспомогательные данные (например, токен авторизации или настройки), их необходимо передавать явно в качестве значений, а саму процедуру объявлять с директивой &НаСервереБезКонтекста.
Посмотрим на пример правильного оформления серверной функции запроса:
&НаСервереБезКонтекста
Функция ПолучитьСписокДляВыбора(Знач ТекстПоиска, Знач ТокенАвторизации)
Результат = Новый Массив;
HTTPЗапрос = Новый HTTPЗапрос();
HTTPЗапрос.АдресРесурса = "/api/v2/suggest/party";
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/xml");
HTTPЗапрос.Заголовки.Вставить("Accept", "application/xml");
HTTPЗапрос.Заголовки.Вставить("Authorization", "Token " + ТокенАвторизации);
HTTPЗапрос.УстановитьТелоИзСтроки("<req><query>" + ТекстПоиска + "</query></req>");
Соединение = Новый HTTPСоединение("dadata.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL);
ОтветHTTP = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
Если ОтветHTTP.КодСостояния = 200 Тогда
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ОтветHTTP.ПолучитьТелоКакСтроку());
ЧтениеXML.ПерейтиКСодержимому();
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();
Если ОбъектXDTO.Свойства().Получить("suggestions") <> Неопределено Тогда
Если ТипЗнч(ОбъектXDTO.suggestions) = Тип("СписокXDTO") Тогда
Для Каждого ЭлементXDTO Из ОбъектXDTO.suggestions Цикл
Результат.Добавить(Строка(ЭлементXDTO.value));
КонецЦикла;
ИначеЕсли ТипЗнч(ОбъектXDTO.suggestions) = Тип("ОбъектXDTO") Тогда
Результат.Добавить(Строка(ОбъектXDTO.suggestions.value));
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Разберем, как передавать сформированный список подсказок пользователю без сброса текста. Вместо ручной работы с Элемент.СписокВыбора платформа предоставляет параметр события ДанныеВыбора.
Выполним следующие действия в обработчике события АвтоПодбор:
СписокЗначений и помещаем ее в параметр ДанныеВыбора.СтандартнаяОбработка = Ложь, сообщая платформе, что список подсказок сформирован программно.Ожидание = Истина, чтобы платформа отправляла запрос только после небольшой паузы в наборе текста пользователем.Посмотрим на реализацию клиентского обработчика:
&НаКлиенте
Процедура ПолеПоискаАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
Если СтрДлина(СокрЛП(Текст)) < 3 Тогда
Возврат;
КонецЕсли;
// Включаем ожидание окончания набора текста пользователем
Ожидание = Истина;
СтандартнаяОбработка = Ложь;
МассивПодсказок = ПолучитьСписокДляВыбора(Текст, ТокенСервиса);
СписокПодсказок = Новый СписокЗначений;
Для Каждого Вариант Из МассивПодсказок Цикл
СписокПодсказок.Добавить(Вариант, Вариант);
КонецЦикла;
ДанныеВыбора = СписокПодсказок;
КонецПроцедуры
Проанализируем свойства поля ввода в палитре свойств, которые влияют на ввод текста:
Ложь). При включенном свойстве поле не позволяет оставлять произвольный текст, не входящий в перечень значений.Не обновлять или При изменении значения, чтобы платформа не перезаписывала строку пользователя в процессе интерактивного набора.Соблюдение этих правил гарантирует стабильную работу поля ввода, отсутствие задержек интерфейса и корректное отображение выпадающего списка подсказок.