При реализации собственной логики быстрого выбора элементов пользователи и разработчики часто сталкиваются с неприятным поведением интерфейса: после набора нескольких символов (например, артикула или кода) и срабатывания события автоподбора появляется выпадающий список вариантов, но набранный текст в поле ввода внезапно исчезает. Разберем по шагам, почему возникает такое поведение платформы 1С:Предприятие 8.3 и как правильно настроить элементы управления и модуль менеджера для стабильной работы подбора.
Проанализируем механику работы поля ввода при переопределении стандартного поиска. В стандартном режиме платформа 1С пытается сопоставить редактируемый текст с представлениями элементов, которые возвращаются в коллекции ДанныеВыбора. Если в обработчике события АвтоПодбор программно отключается стандартная обработка и вызывается серверная функция, происходят следующие процессы:
ДанныеВыбора на клиент вызывают обновление внутреннего состояния поля, из-за чего промежуточный буфер ввода очищается, если свойство обновления настроено некорректно.Посмотрим на типичный пример кода обработчика, где возникает данная проблема:
&НаКлиенте
Процедура НоменклатураАвтоПодбор(Элемент, Текст, ДанныеВыбора, Ожидание, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ДанныеВыбора = ПолучитьДанныеВыбораНаСервере(Текст, СписокВидовНоменклатуры, Объект.ПодразделениеИзготовитель);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьДанныеВыбораНаСервере(Знач СтрокаПоиска, Знач СписокВидовНоменклатуры, Знач Исполнитель)
Отбор = Новый Структура;
Отбор.Вставить("СписокВидовНоменклатуры", СписокВидовНоменклатуры);
Отбор.Вставить("Исполнитель", Исполнитель);
Параметры = Новый Структура;
Параметры.Вставить("Отбор", Отбор);
Параметры.Вставить("СтрокаПоиска", СтрокаПоиска);
Возврат Справочники.Номенклатура.ПолучитьДанныеВыбора(Параметры);
КонецФункции
Самое быстрое и прямое решение проблемы в рамках существующего кода на форме — отключить автоматическую синхронизацию вводимого текста с выпадающим списком.
ОбновлениеТекстаРедактирования (или Обновление текста при редактировании).РежимОбновленияТекстаРедактирования.НеИспользовать).В этом режиме платформа перестает принудительно перезаписывать введенную пользователем строку представлениями найденных объектов при перерисовке выпадающего списка, и набранный текст (например, "137") остается в поле в неизменном виде.
Вызов серверных процедур непосредственно из события АвтоПодбор на клиенте создает сетевые задержки при посимвольном вводе и нарушает стандартный конвейер кэширования платформы. Платформа 1С предоставляет более производительный и архитектурно правильный механизм переопределения быстрого выбора — экспортное событие ОбработкаПолученияДанныхВыбора в модуле менеджера прикладного объекта.
Рассмотрим, как реализовать этот подход. На форме полностью очищаем или удаляем клиентский обработчик АвтоПодбор, а в модуль менеджера справочника (например, Справочник.Номенклатура) добавляем процедуру:
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
// Проверяем наличие специфических отборов
Если Параметры.Отбор.Свойство("СписокВидовНоменклатуры") Тогда
СтандартнаяОбработка = Ложь;
ДанныеВыбора = Новый СписокЗначений;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ВидНоменклатуры В(&СписокВидовНоменклатуры)
| И Номенклатура.Наименование ПОДОБНО &СтрокаПоиска
| И НЕ Номенклатура.ПометкаУдаления";
Запрос.УстановитьПараметр("СписокВидовНоменклатуры", Параметры.Отбор.СписокВидовНоменклатуры);
Запрос.УстановитьПараметр("СтрокаПоиска", "%" + Параметры.СтрокаПоиска + "%");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
При таком подходе платформа самостоятельно управляет асинхронными запросами к серверу, сохраняет набранный текст в поле ввода, контролирует фокус и минимизирует объем передаваемых данных по сети.
Если цель переопределения автоподбора заключалась лишь в фильтрации данных по реквизитам текущей формы (например, по виду номенклатуры или подразделению), писать программный код поиска не требуется. Достаточно использовать декларативные настройки:
СвязиПараметровВыбора (или ПараметрыВыбора).Отбор.Подразделение), и соответствующим полем на форме.Важное примечание: при программном заполнении списка через событие АвтоПодбор всегда рекомендуется проверять минимальную длину набранной строки с помощью условия СтрДлина(СокрЛП(Текст)) >= 3, чтобы не перегружать сервер пустыми выборками при начале ввода.