При реализации интерфейсов для отправки SMS-сообщений или работы с полями ограниченной длины часто возникает задача отображать пользователю количество уже введенных или оставшихся символов прямо в процессе набора текста. Обычное событие ПриИзменении для этой цели не подходит, поскольку оно срабатывает только после потери фокуса элементом управления или при нажатии клавиши Enter.
Разберем, почему попытки реализовать подсчет через механизм автоподбора часто приводят к неожиданной очистке поля ввода, и рассмотрим правильные варианты решения этой задачи в 1С.
При попытке использовать событие элемента управления АвтоПодбор разработчики часто сталкиваются с тем, что после небольшой паузы в наборе текст в поле ввода самопроизвольно стирается или курсор перескакивает в начало строки. Проанализируем основные причины такого поведения:
Текст в процедуре автоподбора содержит текущую строку, введенную пользователем. Если присвоить этому параметру число (например, результат вычисления СтрДлина(Текст)), система попытается подставить это число в поле ввода или вовсе сбросит буфер ввода.СтандартнаяОбработка остается равным Истина, платформа при паузе в наборе пытается сопоставить текст с элементами базы данных и, не найдя совпадений, сбрасывает введенную строку к исходному значению реквизита.ТекстРедактирования очищается.Для отслеживания ввода символов в реальном времени в управляемых формах 1С предусмотрено штатное событие поля ввода — ИзменениеТекстаРедактирования. В отличие от автоподбора, оно срабатывает моментально при каждом нажатии клавиши или вставке фрагмента текста без ожидания паузы.
Посмотрим на пример правильной реализации обработчика:
&НаКлиенте
Процедура ТекстСмсИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
// Получаем текущее количество набранных символов
КоличествоСимволов = СтрДлина(Текст);
// Выводим информацию пользователю (например, в надпись на форме)
Элементы.НадписьКоличествоСимволов.Заголовок = "Символов: " + Строка(КоличествоСимволов) + " из 70";
КонецПроцедуры
Важные правила при работе с этим событием:
&НаКлиенте.&НаСервере, иначе фокус слетит с поля редактирования.Текст предназначен только для чтения текущего состояния строки, не перезаписывайте его другими типами данных.Если по каким-либо причинам используется событие АвтоПодбор, необходимо явно отключить системное поведение платформы, чтобы избежать очистки строки.
Разберем по шагам правильный код обработчика:
&НаКлиенте
Процедура ТекстСмсАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
// Отключаем стандартный поиск ссылочных значений
СтандартнаяОбработка = Ложь;
ДанныеВыбора = Неопределено;
// Рассчитываем длину набранного текста
КоличествоСимволов = СтрДлина(Текст);
// Обновляем информационный элемент формы
Элементы.НадписьКоличествоСимволов.Заголовок = "Осталось символов: " + Строка(70 - КоличествоСимволов);
КонецПроцедуры
Если задача заключается исключительно в том, чтобы не позволить пользователю ввести больше определенного количества знаков (например, не более 70 символов для одного SMS-сообщения), самым надежным и простым решением является установка жесткого ограничения на тип данных реквизита.
Рассмотрим порядок действий:
Строка и задаем фиксированную длину (например, 70 знаков).В этом случае платформа на уровне интерфейса заблокирует ввод лишних символов, и пользователю физически не удастся превысить установленный лимит.
Для гарантированной проверки текста перед выполнением целевого действия (например, перед отправкой сообщения) рекомендуется добавить валидацию в событие ПриИзменении или в процедуру нажатия командной кнопки:
&НаКлиенте
Процедура ОтправитьСМС(Команда)
Если СтрДлина(Объект.ТекстСмс) > 70 Тогда
ПоказатьПредупреждение(, "Длина сообщения превышает допустимый лимит в 70 символов!");
Возврат;
КонецЕсли;
// Вызов процедуры отправки
ОтправитьСообщениеНаСервере();
КонецПроцедуры