Как реализовать поиск по мере ввода текста в поле 1С и избежать очистки поля

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разберем частую задачу разработчиков 1С: требуется организовать динамический поиск по справочнику или таблице прямо во время набора текста в поле ввода, то есть при нажатии каждого нового символа. Стандартный обработчик ПриИзменении для этого не подходит, так как он срабатывает только при нажатии клавиши Enter или потере фокуса полем ввода.

Почему возникают сложности при посимвольном поиске

Когда разработчик пытается привязать процедуру поиска к событию ИзменениеТекстаРедактирования, он часто сталкивается со следующей проблемой: после ввода первого же символа происходит поиск, однако введенный текст в поле очищается, а фокус сбрасывается.

Выясним причину такого поведения платформы 1С. В управляемых формах во время посимвольного набора введенный текст еще не записывается в связанный реквизит формы — он находится в текущем параметре редактирования. Если во время ввода происходит контекстный вызов сервера (процедура с директивой &НаСервере), платформа выполняет синхронизацию всей формы с сервером. Поскольку реквизит формы еще не содержит новый символ, сервер возвращает старое состояние формы. В результате введенный текст стирается, а редактирование прерывается.

Способ 1. Использование события ИзменениеТекстаРедактирования и обработчика ожидания

Чтобы избежать сброса ввода и частых обращений к серверу при каждом нажатом символе, применим обработчик ожидания с помощью метода ПодключитьОбработчикОжидания.

Рассмотрим алгоритм действий по шагам:

  1. В событии элемента формы ИзменениеТекстаРедактирования перехватываем введенный текст из параметра ТекстРедактирования и сохраняем его в переменной формы или временном реквизите.
  2. Отключаем ранее запущенный обработчик ожидания с помощью ОтключитьОбработчикОжидания, если пользователь продолжает набирать текст.
  3. Подключаем однократный обработчик ожидания с паузой (например, 0.3–0.5 секунды). Поиск выполнится только тогда, когда пользователь сделает небольшую паузу в наборе.

Посмотрим на пример реализации данного подхода на клиенте:


&НаКлиенте
Процедура ИмяПоляИзменениеТекстаРедактирования(Элемент, ТекстРедактирования, СтандартнаяОбработка)
    СохраняемыйТекстПоиска = ТекстРедактирования;
    ОтключитьОбработчикОжидания("ВыполнитьПоискНаСервере");
    ПодключитьОбработчикОжидания("ВыполнитьПоискНаСервере", 0.4, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьПоискНаСервере()
    // Вызываем процедуру поиска, передавая накопленный текст
    ОбновитьРезультатыПоиска(СохраняемыйТекстПоиска);
КонецПроцедуры

Способ 2. Оптимизация серверных вызовов через &НаСервереБезКонтекста

Если для выполнения поиска необходимо обратиться к базе данных, важно минимизировать передаваемые данные. Применение директивы &НаСервереБезКонтекста гарантирует, что контекст формы не отправляется на сервер и не перезатирает текущее состояние редактируемого поля на клиенте.

Проанализируем пример вызова без контекста:


&НаСервереБезКонтекста
Функция НайтиДанныеНаСервере(Знач ТекстЗапроса)
    // Выполняем запрос к базе данных без передача контекста формы
    // Возвращаем результат или массив найденных ссылок
КонецФункции

Способ 3. Использование штатного события АвтоПодбор

Если задача заключается в том, чтобы предложить пользователю выпадающий список подсказок по мере ввода, правильным решением будет использование события АвтоПодбор элемента формы.

  1. В свойствах поля ввода убедимся, что включено свойство АвтоВыборНезаполненного или активирован режим автоподбора.
  2. В обработчике события АвтоПодбор устанавливаем параметр СтандартнаяОбработка = Ложь.
  3. Заполняем параметр ДанныеАвтоПодбора списком значений, которые должны отобразиться в выпадающем списке под полем.

&НаКлиенте
Процедура ИмяПоляАвтоПодбор(Элемент, Текст, ДанныеАвтоПодбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ДанныеАвтоПодбора = ПолучитьВариантыПодбора(Текст);
КонецПроцедуры

Способ 4. Посимвольный фильтр в динамическом списке

В случаях, когда результат поиска отображается в форме списка (например, справочника "Номенклатура"), эффективным решением будет изменение отбора динамического списка. При изменении элемента отбора через КомпоновщикНастроек с видом сравнения Содержит перезагрузка управляемой формы не происходит, а фокус ввода сохраняется в поле редактирования.

Как управлять фокусом и сбросить выделение текста

Иногда при программной установке фокуса через ЭтаФорма.ТекущийЭлемент = Элементы.ИмяПоля платформа выделяет весь текст в поле. Чтобы снять выделение и переместить курсор в конец введенной строки, достаточно сразу после установки фокуса очистить свойство ВыделенныйТекст:


ЭтаФорма.ТекущийЭлемент = Элементы.ПоискТекст;
Элементы.ПоискТекст.ВыделенныйТекст = "";

Такой подход позволяет сохранить удобство ввода для пользователя и корректно отработать сценарий интерактивного поиска.

← На главную