Рассказали, как использовать CSS (язык стилей и управления поведением элементов) и JavaScript (язык программирования для веб-разработки) при работе с 1С-интерфейсом.
Давайте изучим работу с CSS и JavaScript на примере создания индикатора, который показывает, сколько символов осталось доступно для ввода в текстовое поле.
Демонстрацию я проведу на базе демоконфигурации «Управляемое приложение» на платформе 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Документа =
"<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 -->
| &ТекстHTML&
| <script>
| // Script
| &ТекстJS&
| </script>
| </body>
|</html>";
ТекстHTMLДокумента = СтрЗаменить(ТекстHTMLДокумента, "&ТекстHTML&", ТекстHTML());
ТекстHTMLДокумента = СтрЗаменить(ТекстHTMLДокумента, "&ТекстСтилей&", ТекстCSS());
ТекстHTMLДокумента = СтрЗаменить(ТекстHTMLДокумента, "&ТекстJS&", Текст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-документа выглядит следующим образом:
- Элемент-индикатор (тег div).
- Цветной ползунок (вложенный div).
- Текстовый элемент (p), показывающий количество символов.
Язык CSS
HTML сам по себе не определяет визуальное оформление, за это отвечает CSS.
Для стилизации используются селекторы:
- По имени тега (например, div {}). Такой подход недостаточно гибок и редко применяется.
- По ID элемента (например, #myid {}). Требует уникальности ID.
- По имени класса (например, .info {}). Этот метод предпочтителен, так как позволяет управлять стилями динамически.
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, чтобы вызвать функцию updateText(), объявленную в модуле JavaScript:
&НаКлиенте
Процедура ОбновитьHTMLИндикатор()
Если Не HTMLЭлементыИнициализированы Тогда
Возврат;
КонецЕсли;
ТекДлина = СтрДлина(Элементы.ДополнительнаяИнформация.ТекстРедактирования);
КонтекстОкнаHTML.updateText(ТекДлина);
КонецПроцедуры
Изменяем стили
Чтобы цветовой индикатор при изменении строки менял свою длину и цвет, нам нужно повлиять на значения параметров стилей, которые сейчас находятся в отдельном модуле CSS. Однако есть и другие варианты, как можно изменить стиль элемента.
Среди стилей нашего класса fillbar нас интересуют два: width (ширина) и background-color (цвет заливки). Если их прописать непосредственно в коде HTML, то определение тега будет выглядеть так:
&НаСервере
Функция Текст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: добавляем новые элементы.
- CSS: описываем стили с использованием градиентов, теней и трансформаций.
- JavaScript: создаем функцию для плавного изменения цвета и положения стрелки.
Дополним код HTML новыми элементами, а в CSS опишем стили для новых классов:
Функция ТекстHTML()
Возврат
"
| ...
| <div class=""arrow_wrap""> // подложка спидометра
| <div class=""arrow""> // из этого сделаем стрелку
| </div>
| </div>
|</div>";
КонецФункции
Функция ТекстCSS()
Возврат
"...
|.arrow_wrap {
| position: relative;
| margin-top: 50px;
| width: 100px;
| height: 50px;
| min-width: 104px;
| min-height: 27px;
| border: 1px solid #aaa;
| border-radius: 50% 50% 0 0;
| box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2), // тень
| 5px 5px 10px rgba(0, 0, 0, 0.1);
| background: linear-gradient(217deg, // градиент
| rgba(255, 150, 150, 0.8),
| rgba(255, 150, 150, 0) 70.71%),
| linear-gradient(127deg,
| rgba(150, 255, 150, 0.8),
| rgba(150, 255, 150, 0) 70.71%),
| linear-gradient(336deg,
| rgba(150, 150, 255, 0.8),
| rgba(150, 150, 255, 0) 70.71%);
|}
|.arrow {
| position: absolute;
| width: 30px;
| height: 5px;
| border-radius: 10px;
| top: 45px;
| left: 20px;
| transform-origin: right center 0;
|
| background-color: rgb(0, 200, 0); // эти два свойства будем менять из кода
| transform: rotate(90deg);
|}";
КонецФункции
Ключевые моменты CSS-трансформаций:
- transform-origin задает точку вращения.
- transform указывает угол поворота.
Осталось добавить код на JS, который будет «двигать» стрелку:
Функция ТекстJavaScript()
Возврат "
| ...
|function duePersent(num) {
| return Math.round((maxLenght - num) / maxLenght * 100);
|}
|function updateArrow(num) {
| var item = document.querySelector('.arrow');
|
| var due = duePersent(num);
| var deg = 180 - Math.round(due*180/100);
| var rr = 200 - Math.round(due*200/100);
| var gg = Math.round(due*200/100);
|
| var transformValue = `rotate(${deg}deg)`;
| var bgcValue = `rgb(${rr}, ${gg}, 0)`;
|
| item.style.backgroundColor = bgcValue;
| item.style.transform = transformValue;
|}
|function updateAll(num) {
| var count = num;
| if (num > maxLenght) {
| count = maxLenght;
| }
|
| updateText(count);
| fillColor(count);
| updateArrow(count);
|}";
КонецФункции
Поведением стрелки управляет функция updateArrow(). Цвет и угол наклона устанавливаются из рассчитанных значений CSS-свойств через style. А сложное представление самих значений формируется путем шаблонизации строк. Такое возможно, если заключить строки не в кавычки, а в обратные бэктики (клавиша «Ё» на клавиатуре).
Все функции управления поведением мы объединили в одну updateAll(), в которой дополнительно выполняем контроль переполнения значения.
&НаКлиенте
Процедура ОбновитьHTMLИндикатор()
Если Не HTMLЭлементыИнициализированы Тогда
Возврат;
КонецЕсли;
ТекДлина = СтрДлина(Элементы.ДополнительнаяИнформация.ТекстРедактирования);
КонтекстОкнаHTML.updateAll(ТекДлина);
КонецПроцедуры
CSS-анимации
Для создания эффекта тряски при переполнении мы используем CSS-анимации с keyframes.
Функция ТекстCSS()
Возврат
"...
|@keyframes bounce {
| 0% {
| transform: translateY(-2px);
| }
|
| 20% {
| transform: translateY(2px);
| }
|
| 40% {
| transform: translateY(-1px);
| }
|
| 60% {
| transform: translateY(1px);
| }
|
| 80% {
| transform: translateY(-1px);
| }
|
| 100% {
| transform: translateY(0);
| }
|}
|
|.modal-error {
| animation: bounce 0.3s; // общая продолжительность сценария анимации
|}";
КонецФункции
В случае ошибки будет добавлен класс modal-error, который запускает анимацию.
Функция ТекстJavaScript()
Возврат "
|var arrowBody = document.querySelector("".arrow_wrap""); // переменная модуля для доступа к элементу
|
| ...
|function updateAll(num) {
|
| ...
| if (num > maxLenght) {
| arrowBody.classList.remove(""modal-error""); // удаляем класс, если он был присвоен ранее
| arrowBody.offsetWidth = arrowBody.offsetWidth; // делаем что-то с элементом, чтобы браузер его обновил
| arrowBody.classList.add(""modal-error""); // снова присваиваем класс, чтобы возбудить анимацию
| }
|}";
КонецФункции
Заключение
Я постарался показать основные приемы работы с HTML, CSS и JavaScript в 1С. Эти технологии открывают практически безграничные возможности для создания интерфейсов, когда стандартных инструментов 1С недостаточно.
Ознакомиться с полным кодом и протестировать его можно по ссылке: CodePen.
Остались вопросы?
Проконсультируйтесь с нашими специалистами