Содержание
Стас Ганиев, автор ТГ-канала OneSCast | 1С Предприятие, а также сооснователь IT-сообщества DevDV.ru и автор контента на Infostart.ru. В данной статье эксперт привел основные базовые возможности элемента «Поле HTML документа», достаточные для решения широкого круга задач.
Введение
Все слышали про этот элемент формы, но не многие его используют. Еще меньше 1С-ников знают, на что на самом деле способен этот элемент диалога.
Ниже привел несколько вариантов использования поля HTML документов для решения задач в 1С, а также привел пример реализации для некоторых из них.
Итак, что же это за элемент формы?
Поле HTML документа — это возможность использовать движок интернет-браузера у себя на форме, прямо в 1С. По факту, это и есть интерфейс браузера на вашей форме, он даже использует то же самое программное ядро Webkit, что и браузер Google Chrome. А это значит, что с объектом поля HTML документа возможны все те же операции (местами с ограничениями), что и в полноценном браузере, включая использование веб-технологий и инструментов управления веб-приложениями.
Для чего можно использовать
В вопросах организации интерфейса в 1С поле HTML документа может быть полезным в следующих задачах:
- Обеспечить доступ к веб-интерфейсу сторонней конфигурации.
- Специализированные элементы диалога формы.
- Альтернативные элементы интерфейса.
- Отображение макетов печатных форм. Такой элемент диалога можно наблюдать в «1С: Документооборот», когда при подготовке документа рядом в этой же форме можно наблюдать миниатюру готового документа (вроде предварительного просмотра).
- Непосредственное отображение буквальной страницы сайта. Довольно редкий кейс, но иногда может пригодиться. Для этого достаточно присвоить элементу поля URL-адрес сайта.
- Запуск кода на языке JavaScript, с помощью которого можно реализовать то, что нельзя сделать на языке 1С.
- Реализация крутых редакторов текста, таких как редактор кода в IS Toolkit.
Остановимся подробнее на первых трех пунктах.
Открываем окно в другую конфигурацию
Этот пример начнем с рассмотрения того, как внедрить элемент «Поле HTML документа» в форму. Все примеры в статье реализованы в демонстрационной конфигурации «Управляемое приложение» на платформе 8.3.23.
Итак, допустим, нам надо предоставить администратору доступ к настройкам сразу двух конфигураций из одной формы, чтобы ему не приходилось запускать вторую конфигурацию. (Внимание! Пользовательская лицензия при этом всё равно будет использована, так как мы поднимаем отдельный веб-клиент).
Для начала на форме обработки «АдминистративныйСервис» создаем новый реквизит формы «ВебСеанс» с типом «Строка» неограниченной длины. Размещаем его в диалоге и устанавливаем вид элемента «Поле HTML документа».
В обработчике «ПриСозданииНаСервере()» пишем следующий код:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) НастройкиПодключения = ПолучитьНастройкиПодключения(); // пользователь и пароль в подключаемой базе Пользователь = НастройкиПодключения.Пользователь; Пароль = НастройкиПодключения.Пароль; // строка подключения зависит от наличия авторизации ТребуетсяАвторизация = ЗначениеЗаполнено(Пользователь) Или ЗначениеЗаполнено(Пароль); // URL-ссылка публикации веб-клиента, например: http://127.0.0.1:8080/demo/ АдресБазы = НастройкиПодключения.АдресБазы; ПараметрЗапуска = НастройкиПодключения.ПараметрЗапуска; Если ТребуетсяАвторизация Тогда Шаблон = "%1/?n=%2&p=%3&c=%4"; АдресПодключения = СтрШаблон(Шаблон, АдресБазы, Пользователь, Пароль, ПараметрЗапуска); Иначе Шаблон = "%1/?&c=%2"; АдресПодключения = СтрШаблон(Шаблон, АдресБазы, ПараметрЗапуска); КонецЕсли; ВебСеанс = АдресПодключения; КонецПроцедуры
Суть работы поля HTML документа заключается в том, что оно, как браузер, отображает то, что приходит в «поток вывода». Другими словами, это та строковая информация, которую мы присваиваем реквизиту «ВебСеанс» (последняя строка процедуры из примера). Точно так же мы можем передать в реквизит URL-адрес сайта, и тогда будет загружена страница сайта. Можно даже передать полную строку HTTP-запроса и получить визуальное представление результата (но для этого есть инструменты получше). Но самое интересное — это возможность передать элементу полную HTML-верстку страницы или отдельного объекта интерфейса, стилизовать его с помощью CSS, а также добавить интерактив с использованием языка JavaScript. Об этом в следующем примере.
Вернемся к примеру и остановимся на параметре «ПараметрЗапуска». Он необходим для того, чтобы на стороне запускаемой базы можно было по его значению переопределить интерфейс приложения в обработчике «ПередНачаломРаботыСистемы()» модуля приложения. Например, запустить конфигурацию в режиме рабочего стола, чтобы не мешали лишние меню навигации.
Если нет такого элемента, мы его создадим сами
Второй пример — это использование произвольной верстки HTML-элемента. Здесь мы создадим поле на форме заказа с историей статусов:
Разместим поле HTML документа «ИсторияСостояний» на форме заказа. Поскольку код верстки со стилизацией может быть достаточно объемным, его обычно выносят в отдельные текстовые макеты. Добавим к документу «Заказ» новый макет «ИсторияСтатусов» и заполним его следующим текстом:
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> p { margin: 0; padding: 0; } .wrap { border: 2px solid #dddd11; border-radius: 5px; padding: 5px; } .status { font-size: 12px; margin-bottom: 7px; padding: 3px; border-radius: 5px; display: flex; justify-content: space-between; } .status-opened { background-color: #ddffdd; } .status-work { background-color: #dddddd; } .status-closed { background-color: #ffdddd; } </style> </head> <body> <div class="wrap"> <!-- начало блока элемента --> <div class="status status-opened"> <p><a href="#" class="link-opened">Открыт</a></p> <p>13.02.2023</p> </div> <!-- конец блока элемента --> <div class="status status-work"> <p><a href="#" class="link-work">В работе</a></p> <p>17.02.2023</p> </div> <div class="status status-closed"> <p><a href="#" class="link-closed">Закрыт</a></p> <p>27.04.2023</p> </div> </div> </body> </html>
В обработчике формы «ПриСозданииНаСервере()» добавим следующий код:
ДокументОбъект = РеквизитФормыВЗначение("Объект"); МакетВерстки = ДокументОбъект.ПолучитьМакет("ИсторияСтатусов"); ИсторияСостояний = МакетВерстки.ПолучитьТекст();
При этом сразу получим результат, изображенный на рисунке выше.
Но нам нужен «живой» элемент, который будет изменяться динамически в зависимости от происходящих процессов.
Для этого в HTML-коде (см. листинг выше) нужно программно собрать блок body, состоящий из отдельных элементов-статусов, первый из которых выделен комментариями. Сделать это можно несколькими способами, мы проделаем следующее:
Шаг 1. Вынесем получение шаблона текста для элемента в отдельную функцию.
&НаСервере Функция HTMLТекстЭлементСтатус() Результат = " |<div class=""status %1""> | <p> | <a href=""#"" class=""link-%1"">%2</a> | </p> | <p>%4</p> |</div>"; Возврат Результат; КонецФункции
Шаг 2. Заменим в макете код тела элемента на идентификатор и вынесем формирование виджета в отдельную процедуру.
&НаСервере Процедура ОбновитьВиджетСтатусов() ДокументОбъект = РеквизитФормыВЗначение("Объект"); ТекстВерстки = ДокументОбъект.ПолучитьМакет("ИсторияСтатусов").ПолучитьТекст(); ТекстВерстки = СтрЗаменить(ТекстВерстки, "%БлокСтатусов%", HTMLТекстБлокСтатусов()); ИсторияСостояний = ТекстВерстки; КонецПроцедуры
Шаг 3. Реализуем функцию формирования блока виджета.
&НаСервере Функция HTMLТекстБлокСтатусов() ИсторияСтатусов = ПолучитьИсториюСтатусов(); ШаблонЭлементаСтатус = HTMLТекстЭлементСтатус(); Фрагменты = Новый Массив; МенеджерСтатусов = Перечисления.СостоянияЗаказов; ИменаКлассов = Новый Соответствие; ИменаКлассов.Вставить(МенеджерСтатусов.Открыт, "status-opened"); ИменаКлассов.Вставить(МенеджерСтатусов.ВРаботе, "status-work"); ИменаКлассов.Вставить(МенеджерСтатусов.Выполнен, "status-work"); ИменаКлассов.Вставить(МенеджерСтатусов.Закрыт, "status-closed"); Для Каждого СтрокаСтатус Из ИсторияСтатусов Цикл ТекстЭлемента = СтрШаблон(ШаблонЭлементаСтатус, ИменаКлассов[СтрокаСтатус.Статус], Строка(СтрокаСтатус.Статус), Формат(СтрокаСтатус.ДатаСтатуса, "ДЛФ=D")); Фрагменты.Добавить(ТекстЭлемента); КонецЦикла; Возврат СтрСоединить(Фрагменты, Символы.ПС); КонецФункции
Осталось только реализовать функцию «ПолучитьИсториюСтатусов()», которая зависит от функционала конкретной конфигурации.
Результат отображения варианта истории в таком виджете:
Альтернативный интерфейс
С помощью поля HTML документа можно реализовать не только отдельные элементы формы, но и интерфейс главного окна приложения, придав ему индивидуальный дизайн. Если открыть главное окно приложения в режиме полноэкранного рабочего стола или киоска и использовать два поля HTML документа, то можно получить такой вариант интерфейса конфигурации:
Немного о дополнительных возможностях
Где отлаживать HTML-код?
Как вы заметили, код наполнения поля может быть достаточно объемным. И чтобы не допустить ошибок при его написании, а также иметь возможность предварительного просмотра результата, используйте сторонние редакторы.
Текст приведенного примера набирался в онлайн-консоли CodePen (https://codepen.io/pen/). Помимо него, можно использовать любой другой сервис:
- PlayCode — https://playcode.io/
- Codesandbox — https://codesandbox.io/
- JS Fiddle — https://jsfiddle.net/
Это так называемые «песочницы» для быстрого набора и проверки кода, использующего веб-технологии. При желании можете использовать полноценный редактор кода, например VSCode.
А этот ресурс рекомендую как отличный путеводитель по HTML-тегам и CSS-свойствам.
Отлавливаем события на элементе
Давайте немного копнем поглубже и посмотрим, что происходит при интерактивных действиях на элементе «Поле HTML документа»? В примере с виджетом неспроста использованы ссылки в названиях статусов. Дальше поставим задачу определить, на какую именно ссылку нажал пользователь, чтобы понимать, какие дальнейшие действия следует предпринять.
У поля HTML документа есть событие «ПриНажатии», создадим для него обработчик:
Вторым параметром в этот обработчик передаются «ДанныеСобытия» — упакованная структура с подробным описанием текущего (на момент нажатия) состояния как элемента в целом, так и конкретного элемента верстки — ссылка с тегом <a> в нашем случае. Вот некоторые свойства данных, которых будет достаточно для решения подавляющего большинства задач при 1С-разработке:
- ДанныеСобытия.Element.className — строка с перечислением CSS-классов элемента. Позиционирование на элементах по именам классов — это лишь один из способов. Также позиционирование возможно по идентификаторам, тегам, родительским или дочерним элементам — всё зависит от стратегии работы со структурой документа и решаемой задачи. Если элементу задано несколько классов, то их имена разделяются пробелом.
- ДанныеСобытия.Element.innerHTML — полное содержание активного элемента. В нашем случае здесь будет наименование статуса. В общем же случае здесь присутствует HTML-код, вложенный в текущий тег.
- ДанныеСобытия.Element.tagName — имя тега текущего элемента.
- ДанныеСобытия.Element.outerHTML — HTML-код текущего элемента. По сути это содержимое свойства innerHTML, включая его обертку в виде описания самого текущего элемента.
- ДанныеСобытия.Event.type — тип события, выполняемого над элементом.
- ДанныеСобытия.Event.x и ДанныеСобытия.Event.y — точное положение курсора мыши в пикселях в момент клика на элементе.
Нам необходимо определить, на какой статус нажал пользователь, чтобы понять, какие дальнейшие действия от нас требуются. Для этого используем имя CSS-класса текущего элемента HTML-верстки:
&НаКлиенте Процедура ИсторияСостоянийПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка) Классы = СтрРазделить(ДанныеСобытия.Element.className, " ", Ложь); Если Классы.Найти("link-opened") <> Неопределено Тогда // обработка статуса "открыт" ИначеЕсли Классы.Найти("link-work") <> Неопределено Тогда // обработка статуса "в работе" // и т.д. КонецЕсли; КонецПроцедуры
Размещение стилей CSS
Стили CSS — это отдельный специализированный язык описания стилей для отдельных блоков, тегов, классов, словом любого элемента HTML-верстки документа. На этом языке описываются взаиморасположение, размеры, цвета, шрифты, тени, а также трансформации и анимации для элементов.
Код CSS сам по себе может быть очень объемным, и в классической веб-разработке их принято выносить в отдельные файлы или библиотеки. В случае с использованием в формах 1С, мы можем их вынести в отдельные модули или макеты. Это сделает код более читабельным и понятным.
Вместо заключения
В этой статье я привел основные базовые возможности элемента «Поле HTML документа», но достаточные для решения широкого круга задач. Если эта тема окажется интересной, то в одной из следующих частей я расскажу про работу с кодом JavaScript и манипуляцию версткой с его помощью, а также поговорим о возможностях CSS для создания анимаций и интерактива.
Остались вопросы?
Проконсультируйтесь с нашими специалистами