Возможности поля HTML-документа, часть 2. Внедряем CSS и JS

от автора

В прошлой статье я рассказал, какие возможности скрывает в себе поле HTML-документа, выведенное на форму 1С. Сегодня подробнее остановлюсь на возможностях языков CSS (язык стилей и некоторых элементов поведения) и JavaScript (язык программирования, используемый в веб-разработке), которые могут пригодиться в работе с 1С-интерфейсом.

Демонстрационный пример

Работу с JS и CSS рассмотрим на примере разработки вот такого индикатора, который будет показывать для текстового поля, сколько символов еще можно напечатать.

Пример я буду реализовывать на демоконфигурации «Управляемое приложение», платформа 8.3.25.

Подготовка элемента формы и базовое наполнение

Подключим наш индикатор к полю с дополнительной информацией на форме элемента контрагента.

Наполним текст поля HTML-документа базовой разметкой. Можете запомнить этот шаблон, чтобы использовать его по умолчанию для новых элементов.

<html>   <head>     <meta http-equiv="content-type" content="text/html;charset=utf-8">     <link rel="stylesheet" type="text/css" href="__STYLE__">     <style type="text/css">       /* Styles */     </style>   </head>   <body>     <!-- HTML code -->     <script>       // Script     </script>   </body> </html>

В тексте HTML-документа используется сразу три языка:

  • язык разметки HTML,

  • язык стилей CSS,

  • язык программирования поведения JavaScript.

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

Инициализацию поля HTML-документа выполним в процедуре, вызываемой из обработчика ПриСозданииНаСервере(), а отдельные смысловые части вынесем в соответствующие функции:

&НаСервере Процедура ИнициализироватьHTMLИндикатор()  ТекстHTMLДокумента =  "<html> |  <head> |    <meta http-equiv=""content-type"" content=""text/html;charset=utf-8""> |    <link rel=""stylesheet"" type=""text/css"" href=""__STYLE__""> |    <style type=""text/css""> |      /* Styles */ |      &amp;ТекстСтилей&amp; |    </style> |  </head> |  <body> |    <!-- HTML code --> |    &amp;ТекстHTML&amp; |    <script> |      // Script |      &amp;ТекстJS&amp; |    </script> |  </body> |</html>";  ТекстHTMLДокумента = СтрЗаменить(ТекстHTMLДокумента, "&amp;ТекстHTML&amp;", ТекстHTML()); ТекстHTMLДокумента = СтрЗаменить(ТекстHTMLДокумента, "&amp;ТекстСтилей&amp;", ТекстCSS()); ТекстHTMLДокумента = СтрЗаменить(ТекстHTMLДокумента, "&amp;ТекстJS&amp;", ТекстJavaScript());  HTMLИндикатор = ТекстHTMLДокумента;  КонецПроцедуры  Функция ТекстHTML()  Возврат  "<div class=""progressbar""> |  <div class=""fillbar""> |  </div> |  <p class=""info""> |    145 |  </p> |</div>";  КонецФункции  Функция ТекстCSS()  Возврат  ".progressbar { |  position: relative; |  width: 104px; |  height: 27px; |  border: 1px solid #0aa; |  border-radius: 4px; |}  |.fillbar { |  position: absolute; |  top: 2px; |  left: 2px; |  width: 45px; |  height: 21px; |  border: 1px solid #aa0; |  border-radius: 3px; |  background-color: #aa0; |  z-index: 2; |}  |.info { |  position: absolute; |  right: 5px; |  top: 8px; |  margin: 0; |  padding: 0; |  font-size: 10px; |  z-index: 3; |}";  КонецФункции  Функция ТекстJavaScript()  Возврат "";  КонецФункции 

В результате при открытии формы, получим статичный элемент индикатора.

Теперь наша задача — вдохнуть в него жизнь и наделить определенным поведением:

  • по мере редактирования поля комментария индикатор должен показывать число оставшихся символов от максимальной длины текста;

  • длина заливки цветом должна соответствовать процентной доле объема текста;

  • цвет заливки будет меняться в зависимости от заполненности поля: зеленый при заполнении до 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, то определение тега будет выглядеть так:

<div class="fillbar" style="width: 45px; background-color: #aa0">

Для работы со стилями из 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Индикатор()  //... КонтекстОкнаHTML.updateText(ТекДлина); КонтекстОкнаHTML.fillColor(ТекДлина);  КонецПроцедуры

Заключение

Конечно, в рамках двух статей невозможно описать все тонкости веб-технологий для поля HTML-документа, ибо они практически безграничны. Моя цель: на простом рабочем примере показать, что из себя представляют новые для 1С-ника языки HTML, CSS и JavaScript. И как их применить при разработке новых интерфейсных элементов, если возможностей 1С недостаточно.


ссылка на оригинал статьи https://habr.com/ru/articles/860106/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *