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

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

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

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

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

Поле HTML-документа удобно использовать в различных задачах, чтобы:

  • предоставить доступ к веб-интерфейсу сторонней конфигурации;

  • использовать дополнительные элементы диалога формы или альтернативные элементы интерфейса;

  • отображать макеты печатных форм. Например, в решении »1С: Документооборот» при подготовке документа в этой же форме можно увидеть миниатюру готового документа, то есть использовать функцию предварительного просмотра;

  • отображать страницу сайта. Редко используется на практике, но тем не менее может пригодиться. Достаточно присвоить элементу поля URL-адрес сайта;

  • запустить код на языке JavaScript. Благодаря этому можно реализовать в программе то, что невозможно сделать на языке 1С;

  • реализовать крутые редакторы текста. Например, редактор кода в IS Toolkit.

Давайте разберем три первых пункта более подробно.

Открываем окно в другую конфигурацию

Для начала нужно добавить элемент »Поле HTML-документа» на форму. Во всех случаях я использовал демо-версию конфигурации «Управляемое приложение» на платформе 8.3.23. Предположим, необходимо предоставить администратору доступ к настройкам сразу для двух конфигураций из одной формы, чтобы не нужно было запускать вторую конфигурацию.

Обратите внимание: пользовательская лицензия в этом случае все равно используется, поскольку необходим отдельный веб-клиент. 

На форме обработки АдминистративныйСервис создайте новый реквизит формы ВебСеанс. Тип реквизита — Строка (длина не ограничена). Установите вид элемента »Поле HTML-документа».

c96b3720be0418138072474e0af8c1ee.png

В обработчике ПриСозданииНаСервере () напишите следующий код:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	НастройкиПодключения = ПолучитьНастройкиПодключения();
	
    // пользователь и пароль в подключаемой базе
	Пользователь = НастройкиПодключения.Пользователь; 
	Пароль = НастройкиПодключения.Пароль;
	
	// строка подключения зависит от наличия авторизации
	ТребуетсяАвторизация = ЗначениеЗаполнено(Пользователь) Или ЗначениеЗаполнено(Пароль);
	
	// 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-элемента. Здесь необходимо создать поле на форме заказа с историей статусов (см. скриншот).

e689d9cc0129841239f10e71d9036173.png

Добавьте поле HTML-документа ИсторияСостояний на форму заказа. Код верстки может быть достаточно большим, поэтому для удобства сформируйте отдельные текстовые макеты. Добавьте к документу Заказ новый макет ИсторияСтатусов и заполните его:





    
    
    
    Document
    



    

Открыт

13.02.2023

В работе

17.02.2023

Закрыт

27.04.2023

В обработчике формы ПриСозданииНаСервере () добавьте следующий код:

ДокументОбъект = РеквизитФормыВЗначение("Объект");
МакетВерстки = ДокументОбъект.ПолучитьМакет("ИсторияСтатусов");
ИсторияСостояний = МакетВерстки.ПолучитьТекст();

Вы сразу получите результат, изображенный на рисунке выше. Чтобы добавить динамический элемент, который будет изменяться в зависимости от происходящих процессов, необходимо выполнить следующие действия. В HTML-коде (см. листинг выше) нужно собрать блок body. Он состоит из отдельных элементов-статусов, первый из которых выделен комментариями. Существует несколько способов, как это сделать. Один из вариантов я описал ниже.

Шаг 1. Создайте отдельную функцию, чтобы получить шаблон текста для элемента.

&НаСервере
Функция HTMLТекстЭлементСтатус()
	
	Результат = "
	|
|

| %2 |

|

%4

|
"; Возврат Результат; КонецФункции

Шаг 2. В макете замените код тела элемента на идентификатор. Вынесите формирование виджета в отдельную процедуру.

&НаСервере
Процедура ОбновитьВиджетСтатусов()
	
	ДокументОбъект = РеквизитФормыВЗначение("Объект");
	ТекстВерстки = ДокументОбъект.ПолучитьМакет("ИсторияСтатусов").ПолучитьТекст();
	
	ТекстВерстки = СтрЗаменить(ТекстВерстки,
		"%БлокСтатусов%",
		HTMLТекстБлокСтатусов());
	
	ИсторияСостояний = ТекстВерстки;
	
КонецПроцедуры

Шаг 3. Добавьте функцию формирования блока виджета.

&НаСервере
Функция HTMLТекстБлокСтатусов()
	
	ИсторияСтатусов = ПолучитьИсториюСтатусов();
	ШаблонЭлементаСтатус = HTMLТекстЭлементСтатус();
	Фрагменты = Новый Массив;
	
	МенеджерСтатусов = Перечисления.СостоянияЗаказов;
	ИменаКлассов = Новый Соответствие;
	ИменаКлассов.Вставить(МенеджерСтатусов.Открыт, "status-opened");
	ИменаКлассов.Вставить(МенеджерСтатусов.ВРаботе, "status-work");
	ИменаКлассов.Вставить(МенеджерСтатусов.Выполнен, "status-work");
	ИменаКлассов.Вставить(МенеджерСтатусов.Закрыт, "status-closed");
	
	Для Каждого СтрокаСтатус Из ИсторияСтатусов Цикл
		
		ТекстЭлемента = СтрШаблон(ШаблонЭлементаСтатус,
			ИменаКлассов[СтрокаСтатус.Статус],
			Строка(СтрокаСтатус.Статус),
			Формат(СтрокаСтатус.ДатаСтатуса, "ДЛФ=D"));
		
		Фрагменты.Добавить(ТекстЭлемента);
		
	КонецЦикла;
	
	Возврат СтрСоединить(Фрагменты, Символы.ПС);
	
КонецФункции

Не забудьте добавить функцию ПолучитьИсториюСтатусов (). Она зависит от функционала конкретной конфигурации. Результат отображения варианта истории выполнен в таком виджете (см. скриншот).

a0211b89f6c0ebdcd1d2ef79ce5c5ed3.png

Альтернативный интерфейс

Используйте поля HTML-документа, чтобы настроить интерфейс главного окна приложения, придав ему индивидуальный дизайн. Чтобы получить такой вариант интерфейса конфигурации (см. скриншот), откройте главное окно приложения в режиме полноэкранного рабочего стола и используйте два поля HTML-документа.

ffd54363815a4031dc8e70952e23bb2f.png

Дополнительные возможности

Где провести отладку HTML-кода?

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

Мне нравится онлайн-консоль CodePen, но есть и другие, не менее удобные сервисы:

Любой из этих сервисов поможет быстро набрать и проверить код. Или используйте полноценный редактор, например VSCode. Еще больше информации по HTML-тегам и CSS-свойствам вы найдете здесь.

Отлавливаем события на элементе

Разберем вопрос подробнее, чтобы понять, что происходит при интерактивных действиях на элементе »Поле HTML-документа». Ссылки в названиях статусов добавлены не просто так (см. пример с виджетом). Следующий шаг — понять, на какую ссылку нажал пользователь и что следует делать дальше. 

У поля HTML-документа есть событие ПриНажатии, создаем для него обработчик.

f844c13a28bc304e156ec43153747279.png

ДанныеСобытия —второй параметр, который передается в обработчик. Это упакованная структура с подробным описанием текущего состояния элемента в целом или конкретного элемента верстки (ссылка с тегом в нашем случае).

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

© Habrahabr.ru