Как реализовать подстановку текста из списка автоподбора с возможностью продолжения ввода

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

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

Анализ проблемы стандартного автоподбора

Стандартный механизм АвтоПодбор работает по принципу «выбрал — завершил». Как только пользователь нажимает Enter или кликает мышью по варианту, событие считается завершенным. Если нам нужно, чтобы после выбора слова «Некрасовское» курсор остался в поле и пользователь мог сразу печатать «Гагарина 5а», стандартных свойств текстового поля будет недостаточно. Проанализируем доступные способы решения этой задачи, от простых манипуляций с событиями до создания собственных элементов управления.

Решение 1. Использование Поля HTML-документа и JavaScript

Это самый гибкий и современный метод, позволяющий полностью контролировать поведение клавиатуры и списков. Мы можем встроить в управляемую форму ПолеHTMLДокумента и использовать мощь JavaScript для обработки ввода.

Разберем логику реализации по шагам:

  1. Разместим на форме элемент ПолеHTMLДокумента.
  2. Внутри HTML-кода создадим обычный input и выпадающий блок div, имитирующий список.
  3. Используем событие onkeydown. При нажатии стрелок «Вверх» или «Вниз» мы будем программно менять value в input, но не будем закрывать список.
  4. Для передачи данных обратно в 1С используем механизм window.external.MessageEvent (для новых версий платформы).

Пример кода внутри HTML-поля для перехвата клавиш может выглядеть так:


inputElement.addEventListener('keydown', function(e) {
    if (e.keyCode === 40) { // Стрелка вниз
        let nextValue = getNextListItemValue();
        inputElement.value = nextValue;
        // Отправляем промежуточное значение в 1С, если нужно
        window.external.postMessage(nextValue);
    }
});

Этот метод позволяет реализовать именно то «интерактивное» поведение, которое требуется: текст подставляется в поле в момент перемещения курсора по списку, но фокус остается на вводе.

Решение 2. Программное управление списком выбора в 1С

Если мы хотим остаться в рамках стандартных элементов, нам придется «обмануть» логику платформы. Мы можем использовать событие АвтоПодбор, установив параметр СтандартнаяОбработка = Ложь. Рассмотрим, как это реализовать.

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

Рассмотрим алгоритм работы через обработчик ожидания:

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

Пример кода для обработки ввода:


&НаКлиенте
Процедура ПолеВводаАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Здесь мы не заполняем ДанныеВыбора, чтобы не открывать стандартное окно
    // Вместо этого вызываем свою логику отображения списка
    ПоказатьСвойСписокПодсказок(Текст);
КонецПроцедуры

Решение 3. Интеграция с внешними API (например, DaData)

Для задач ввода адресов часто эффективнее использовать специализированные сервисы. Они позволяют реализовать логику «разбора» строки. Когда пользователь вводит часть адреса, сервис возвращает структурированный ответ.

Проанализируем ситуацию: если набрать «некрас гагарина», стандартный ФИАС может не справиться. Сервисы типа DaData поддерживают нечеткий поиск. Мы можем реализовать следующий сценарий:

  1. Пользователь вводит текст в свободном формате.
  2. Программа отправляет запрос к API после каждой паузы в наборе.
  3. Результаты отображаются в динамическом списке.
  4. При выборе населенного пункта программа не закрывает ввод, а добавляет пробел и предлагает вводить улицу, при этом контекст поиска сужается до выбранного города.

Это реализуется через метод «склеивания» строк. Проанализируем пример кода, который объединяет уже выбранную часть и новый ввод:


&НаКлиенте
Процедура ОбработкаВыбораИзСписка(ВыбранныйЭлемент)
    // Сохраняем уже введенную структуру (например, город)
    СтруктураАдреса.Город = ВыбранныйЭлемент.Значение;
    
    // Обновляем поле ввода, добавляя пробел для продолжения
    Объект.АдресСтрокой = Строка(ВыбранныйЭлемент.Значение) + " ";
    
    // Устанавливаем курсор в конец строки
    // (требует использования WScript.Shell для имитации нажатия клавиши End)
    УстановитьКурсорВКонецПоля();
КонецПроцедуры

Решение 4. Использование объекта WScript.Shell (Windows)

В некоторых случаях для тонкой настройки поведения текстового поля в тонком клиенте под Windows используют объект WScript.Shell. Это позволяет программно «допечатывать» символы в поле, как будто их нажимает пользователь. Это помогает избежать события ПриИзменении, которое может сработать преждевременно.

Рассмотрим пример, как программно нажать пробел после выбора из списка:


&НаКлиенте
Процедура ДопечататьПробел()
    Попытка
        Shell = Новый COMОбъект("WScript.Shell");
        Shell.SendKeys(" "); // Посылаем нажатие клавиши пробел
    Исключение
        // Обработка ошибки, если COM-объект недоступен
    КонецПопытки;
КонецПроцедуры

Важно: Данный метод является платформозависимым и не будет работать в веб-клиенте или на Linux.

Рекомендации по выбору метода

Подведем итог и выберем оптимальный путь в зависимости от условий задачи:

Помните, что в новых версиях платформы (начиная с 8.3.15) работа с адресами через систему ГАР уже предполагает более продвинутые механизмы разбора строк, поэтому перед написанием своего велосипеда проверьте возможности встроенного адресного классификатора в вашей конфигурации.

← На главную