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

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

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

Анализ причины исчезновения выделения

Для начала проанализируем ситуацию с точки зрения архитектуры платформы. В 1С ПолеВвода базируется на стандартных контролах операционной системы. В интерфейсной логике фокус ввода может находиться только на одном элементе одновременно. Чтобы не дезинформировать пользователя, система скрывает каретку в неактивных полях. В других средах разработки (например, Delphi, .NET или Java Swing) у текстовых полей часто есть свойство типа HideSelection, которое позволяет оставить выделение серым или полупрозрачным, даже если фокус ушел. В управляемых формах 1С такое свойство отсутствует.

Многие разработчики пытаются использовать метод УстановитьГраницыВыделения(), надеясь, что он заставит платформу отрисовать выделение. Однако, как показывает практика, этот метод лишь программно фиксирует координаты (начало и длину) выделенного фрагмента в памяти объекта. Визуальная отрисовка этого фрагмента происходит только в том случае, если элемент является активным (ТекущийЭлемент формы). Как только фокус передается другому объекту, платформа прекращает отрисовку "инверсии" текста.

Вариант 1. Использование Поля HTML документа

Если задача требует обязательного сохранения выделения (например, вы пишете обработку для поиска и замены текста, где пользователь должен видеть найденный кусок, нажимая кнопки "Далее"), самым надежным способом будет использование Поля HTML документа вместо обычного Поля ввода. Рассмотрим этот метод подробнее.

В HTML-контейнере мы имеем полный контроль над отображением через CSS и JavaScript. Мы можем программно управлять выделением с помощью объекта window.getSelection() и стилизовать его так, чтобы оно не исчезало. Разберем по шагам, как это реализовать:

  1. Разместим на форме реквизит с типом Строка и видом Поле HTML документа.
  2. С помощью CSS зададим стиль для псевдоэлемента ::selection. Это позволит нам определить цвет фона и текста даже для неактивного окна в некоторых браузерах (движках).
  3. Напишем JavaScript-код для захвата и сохранения выделения.

Пример программного формирования содержимого для такого поля:


ТекстHTML = "
|<style>
|   ::selection { background: #ffb7b7; color: black; }
|   .persistent-selection { background-color: yellow; }
|</style>
|<div id='content' contenteditable='true'>Ваш текст здесь...</div>";
ЭтаФорма.Элементы.ПолеHTML.УстановитьТекст(ТекстHTML);

Использование contenteditable превращает HTML-поле в полноценный текстовый редактор, где программное выделение через скрипты будет гораздо стабильнее платформенных методов 1С.

Вариант 2. Имитация выделения через изменение фона (подсветка)

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

Для этого удобно использовать УсловноеОформление формы. Процесс выглядит следующим образом:

  1. Создадим на форме вспомогательный реквизит (например, АктивныйИдентификаторСтроки).
  2. В событии ПриАктивизацииСтроки или ПриИзменении поля ввода будем записывать текущее состояние в этот реквизит.
  3. В настройках условного оформления укажем: если текущая строка совпадает с сохраненным идентификатором, покрасить фон поля в светло-синий или желтый цвет.

Это не создаст эффект выделения конкретных букв внутри слова, но четко укажет пользователю, с каким объектом он работал до перехода к кнопкам управления.

Вариант 3. Визуальная имитация через декорации (Labels)

Этот способ считается "хитрым" и подходит для продвинутых интерфейсов. Идея заключается в том, что в момент потери фокуса мы "подменяем" реальное поле ввода статичной картинкой или форматированной строкой.

Разберем алгоритм реализации:

  1. В форме создаем два элемента, расположенных в одной группе: ПолеВвода и ПолеНадписи (вид — Поле декорации).
  2. В обычном состоянии надпись скрыта (Видимость = Ложь).
  3. В событии ПриДеактивизации поля ввода мы считываем границы выделения через ПолучитьГраницыВыделения().
  4. Программно формируем объект ФорматированнаяСтрока, где часть текста, попавшая в границы, выделена другим цветом (свойство ЦветФона).
  5. Присваиваем эту строку в ПолеНадписи, делаем надпись видимой, а само ПолеВвода скрываем.
  6. При получении фокуса обратно (событие ПриАктивизации) — производим обратную замену.

Пример кода для создания форматированной строки с выделением:


// Предположим, ГраницаНачала = 5, ГраницаКонца = 10
Часть1 = Сред(ИсходныйТекст, 1, ГраницаНачала - 1);
ЧастьВыделенная = Сред(ИсходныйТекст, ГраницаНачала, ГраницаКонца - ГраницаНачала);
Часть2 = Сред(ИсходныйТекст, ГраницаКонца);

ТекстДляДекорации = Новый ФорматированнаяСтрока(Часть1, 
    Новый ФорматированнаяСтрока(ЧастьВыделенная, , , ЦветаСтиля.ФонВыделения), 
    Часть2);
Элементы.ДекорацияТекст.Заголовок = ТекстДляДекорации;

Особенности работы в Web-клиенте

Важно помнить, что поведение интерфейса в тонком клиенте и веб-клиенте может различаться. В веб-клиенте отрисовкой занимается браузер. Некоторые современные браузеры по умолчанию оставляют "серое" выделение при переходе фокуса (например, если вы выделили текст в поисковой строке и кликнули на свободное место страницы). Однако ядро 1С активно вмешивается в процесс обработки событий DOM, поэтому рассчитывать на стандартное поведение браузера не стоит. Если ваше приложение ориентировано на работу через браузер, использование Варианта 1 (HTML-поле) является практически единственным стабильным решением.

Рекомендации по UX (пользовательскому опыту)

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

Поэтому, если ваша цель — просто показать, какой фрагмент был выбран, используйте статичную подсветку фона (Вариант 2 или 3), но не пытайтесь имитировать мигающую каретку. Это обеспечит наглядность и сохранит логику работы интерфейса 1С:Предприятие.

Резюме

Выясним кратко основные моменты:

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

← На главную