Возможности поля HTML-документа, часть 2. Внедряем CSS и JS21.11.2024 11:15
В прошлой статье я рассказал, какие возможности скрывает в себе поле HTML-документа, выведенное на форму 1С. Сегодня подробнее остановлюсь на возможностях языков CSS (язык стилей и некоторых элементов поведения) и JavaScript (язык программирования, используемый в веб-разработке), которые могут пригодиться в работе с 1С-интерфейсом.
Демонстрационный пример
Работу с JS и CSS рассмотрим на примере разработки вот такого индикатора, который будет показывать для текстового поля, сколько символов еще можно напечатать.
Пример я буду реализовывать на демоконфигурации «Управляемое приложение», платформа 8.3.25.
Подготовка элемента формы и базовое наполнение
Подключим наш индикатор к полю с дополнительной информацией на форме элемента контрагента.
Наполним текст поля HTML-документа базовой разметкой. Можете запомнить этот шаблон, чтобы использовать его по умолчанию для новых элементов.
В тексте HTML-документа используется сразу три языка:
язык разметки HTML,
язык стилей CSS,
язык программирования поведения JavaScript.
Это видно хотя бы по тому, что у каждого из них свой синтаксис обозначения комментариев. В проектах фронтенд-разработки отдельные модули этих частей выносят в разные файлы, но результат собирается именно в таком виде — весь код в одном файле.
Инициализацию поля HTML-документа выполним в процедуре, вызываемой из обработчика ПриСозданииНаСервере (), а отдельные смысловые части вынесем в соответствующие функции:
В результате при открытии формы, получим статичный элемент индикатора.
Теперь наша задача — вдохнуть в него жизнь и наделить определенным поведением:
по мере редактирования поля комментария индикатор должен показывать число оставшихся символов от максимальной длины текста;
длина заливки цветом должна соответствовать процентной доле объема текста;
цвет заливки будет меняться в зависимости от заполненности поля: зеленый при заполнении до 70%, желтый при 71% — 90%, красный при заполнении более 90% от допустимой максимальной длины.
Анатомия HTML-документа
Прежде чем начать манипуляции с HTML-полем, немного остановимся на том, как оно устроено изнутри.
Язык HTML
HTML-текст нашего элемента буквально рассказывает, какие элементы будут присутствовать в разметке. У нас их всего 3:
сам элемент-индикатор (тег div), обведенный рамкой;
вложенные в него цветовой ползунок (вложенный div);
элемент «параграф» (тег »p»), содержащий строковое представление числа символов.
Язык CSS
Сама по себе HTML-разметка не представляет большого интереса с точки зрения визуального результата. За взаимное расположение элементов и их внешний вид полностью отвечает язык описания стилей CSS.
Чтобы «сопоставить» элемент разметки при описании его стилей, в языке CSS выполняется позиционирование на элементе по так называемому Селектору. Типов селекторов существует с десяток, основные из них:
Позиционирование по имени тега. Например:»div {}» — стили будут применены ко всем элементам с тегом »div». Хотя для некоторых задач это бывает удобно, но в целом такой подход не очень гибкий, поскольку мы жестко привязаны к семантике расстановки HTML-тегов, а их разнообразие не так велико.
Позиционирование по ID элемента:»#myid {}» — применить к элементу с идентификатором myid. Сложность применения такого селектора в том, что идентификаторы должны быть уникальными в рамках всего HTML-документа, и за этим нужно дополнительно следить. К тому же этот подход не рекомендуется Стандартами.
Позиционирование по имени класса:».info {}» (начиная с точки). Такой метод наиболее предпочтителен, и именно он используется в современной веб-индустрии. Управлять классами можно очень гибко, а задавать классы отдельным элементам разметки можно прямо в HTML-тексте в виде отдельного параметра тега class, что и сделано в нашем примере.
Открываем портал в HTML и управляем контекстом элемента
Динамически изменять число символов на индикаторе будем из кода на языке JavaScript, а инициализировать событие обновления будет обработчик текстового элемента формы ИзменениеТекстаРедактирования (). Его единственная задача — вызвать нашу процедуру ОбновитьHTMLИндикатор () (см. ниже).
Заполним текст модуля JS, который возвращает функция ТекстJavaScript ():
Функция ТекстJavaScript()
Возврат "
|var maxLenght = 255; // Переменная, в которой будем хранить максимальную длину текста
|
|function updateText(num) { // Объявляем функцию изменения текста параграфа
| var item = document.querySelector('.info'); // Находим интересующий элемент разметки по селектору
| item.textContent = (maxLenght - num); // Заменяем текстовый контекст элемента
|}";
КонецФункции
А теперь хорошая новость. Все, что объявлено в коде JavaScript, сразу становится доступным «снаружи», для этого не нужно специальным образом объявлять переменные или функции экспортными. Однако нужно заранее позаботиться о наличии «портала» для проникновения в код документа. Таким промежуточным звеном выступает сущность, которую условно назовем «контекст окна HTML». Хранить его будем в отдельной переменной модуля, а инициализировать в обработчике события ДокументСформирован () элемента «Поле HTML-документа».
&НаКлиенте
Перем КонтекстДокументаHTML;
&НаКлиенте
Перем КонтекстОкнаHTML;
&НаКлиенте
Процедура HTMLИндикаторДокументСформирован(Элемент)
Если НЕ HTMLЭлементыИнициализированы Тогда // Атрибут формы для предотвращения повторного запуска
HTMLЭлементыИнициализированы = Истина;
КонтекстДокументаHTML = Элемент.Документ;
КонтекстОкнаHTML = КонтекстДокументаHTML.parentWindow;
Если КонтекстОкнаHTML = Неопределено Тогда
КонтекстОкнаHTML = КонтекстДокументаHTML.defaultView;
КонецЕсли;
КонтекстОкнаHTML.maxLenght = 100; // Инициируем переменную, объявленную в модуле JS
КонецЕсли;
ОбновитьHTMLИндикатор();
КонецПроцедуры
Вызываем функцию JavaScript из кода 1С
Теперь у нас все готово для манипуляции HTML-документом из кода 1С. Задействуем контекст окна HTML, чтобы вызвать функцию updateText (), объявленную в модуле JavaScript:
&НаКлиенте
Процедура ОбновитьHTMLИндикатор()
Если Не HTMLЭлементыИнициализированы Тогда
Возврат;
КонецЕсли;
ТекДлина = СтрДлина(Элементы.ДополнительнаяИнформация.ТекстРедактирования);
КонтекстОкнаHTML.updateText(ТекДлина);
КонецПроцедуры
Изменяем стили на лету
Далее рассмотрим, что мы можем сделать, чтобы цветовой индикатор при изменении длины строки менял свою длину и цвет? Для этого нам нужно повлиять на значения параметров стилей, которые сейчас находятся в отдельном модуле CSS. Однако, как и многое в веб-технологиях, есть и другие варианты изменить стиль элемента.
Так, стили можно непосредственно задать в HTML-элементе в виде атрибута тега style. Причем такие стили будут иметь более высокий приоритет, чем те, что находятся в подключенном модуле. А нам это как раз на руку.
Среди стилей нашего класса fillbar нас интересуют два: width (ширина) и background-color (цвет заливки). Если их прописать непосредственно в коде HTML, то определение тега будет выглядеть так:
Для работы со стилями из JS-кода, у элемента есть служебное свойство style, от которого через точку можно задать значение любого CSS-свойства. С одной оговоркой: если имя свойства составное (как background-color), то в языке JavaScript оно преобразуется в camel-case нотацию и превращается в backgroundColor. Полный текст JS-функции, который управляет цветовым индикатором, будет выглядеть следующим образом:
&НаСервере
Функция ТекстJavaScript()
Возврат "
|// ...
|
|function fillColor(num) {
| // получаем элемент цветового индикатора
| var item = document.querySelector('.fillbar');
| // рассчитываем параметры
| var count = 100 - Math.round((maxLenght - num) / maxLenght * 100);
| var color = ""#0f0"";
| if (count > 70) {color = ""#ff0""}
| if (count > 90) {color = ""#f00""}
| // задаем новые стили заливки
| item.style.width = count + ""px"";
| item.style.backgroundColor = color;
|}";
КонецФункции
Остается только вставить его вызов в процедуру обновления индикатора и наслаждаться результатом.
Конечно, в рамках двух статей невозможно описать все тонкости веб-технологий для поля HTML-документа, ибо они практически безграничны. Моя цель: на простом рабочем примере показать, что из себя представляют новые для 1С-ника языки HTML, CSS и JavaScript. И как их применить при разработке новых интерфейсных элементов, если возможностей 1С недостаточно.