Поле HTML-документа: для чего можно использовать

от автора

Привет, Хабр! Меня зовут Стас Ганиев, программист 1С, в статье рассказал о возможностях поля HTML-документа для решения задач в 1С, а также привел примеры реализации. Далеко не все 1С-разработчики знают, как использовать этот элемент диалога.

Что такое поле HTML-документа? 

Это возможность использовать движок браузера у себя на форме, прямо в 1С. По факту, это и есть интерфейс браузера на вашей форме. Он даже использует то же самое программное ядро Webkit, что и браузер Google Chrome. С объектом поля HTML-документа можно выполнять все те же операции (иногда с ограничениями), что и в полноценном браузере, включая использование веб-технологий и инструментов управления веб-приложениями.

Зачем это нужно

Поле 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, но есть и другие, не менее удобные сервисы:

Любой из этих сервисов поможет быстро набрать и проверить код. Или используйте полноценный редактор, например 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 для создания анимаций и интерактива.


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


Комментарии

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

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