Перейти к содержимому

1С Поле HTML документа — Список

1С Поле HTML документа - Список

Часть 1: 1С Поле HTML документа — Кнопки.
Часть 2: 1С Поле HTML документа — Обмен.
Часть 3: 1С Поле HTML документа — Список.
Часть 4: 1С Поле HTML документа — React Список.

Рассмотрим простой пример использования списка, созданного при помощи HTML, CSS и JavaScript, с возможностью загрузки данных из 1С. За основу будет взята база данных из записи Анализ данных и прогнозирование в 1С — Общая статистика, реализация будет выполнена во внешней обработке.

1. Добавлен макет HTML.

Во внешнюю обработку добавлен макет HTML, содержащий следующий код:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1С Поле HTML документа - Список</title> 
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        body {
            background-color:  rgb(248, 249, 251);
            font-family: Arial, Helvetica, sans-serif;
            color: #2E3440;
        }
        
        /* Элемент списка */
        .item {
            position: relative;
            background-color:  #ECEFF4;
            border-radius: 5px;
            padding: 3px;
            margin: 3px;
            margin-bottom: 3px;
            cursor: pointer;
        }
        .item:hover, .item:hover > div {
            background-color: #E5E9F0;
        }
        .item:active, .item:active > div {
            background-color: #D8DEE9;
        }
        .item:hover .rating {
            opacity: 1;
        }
        
        /* Наименование элемента списка */
        .itemName {
            display: inline-block;
            width: 85%;
            font-size: 12px;
            font-weight: bold;
        }
        
        /* Данные элемента списка */
        .itemData div {
            display: inline-block;
            font-weight: normal;
            font-size: 10px;
        }

        /* Звезда рейтинга */
        .rating {
            position: absolute;
            top: 20%;
            right: 10px;
            opacity: 0.5;
        }
        .yellowStar {
            display: inline-block;
            width: 24px;
            height: 24px;
            background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAhQAAAIUB4uz/wQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIQSURBVEiJtZO7axRRGMV/38yyOySCD4gkIlpJwFikUXzksWujRSwEsREDloYUavIPWFmkFGxSGLEUrBSx0M2a2Ak2KlhoI8RICApmZWd3M8di1zDMzGZnNB4YmHvuPed8331ABmixcEFLhYksGktt/sobRyq3VFaysVoljc5JXYp0q12QId1MK0vVgV54h8npE+C2qQDHjtho7XM3bboOcpoOmbd0ga6nkXbtQG/ooep9Ae2LTP2g5h+0c1S303fvoFq4mmAOsAfPu9JNntiBlthLkO8Hpw/pHsZQolq8x2wKgjWc+qqN8j0WoMX8RcyugfWDBoA+oNCtsg7wgTWwr6BVpPumirfeYQt2AFp3MC38H3PA7IFjY/4McAPQDloL7LaN+TNbh6yKNwmaB/L/aN5ENmXF2jxEbpEq3lnQY2D3X5pvIC5b0X/2h4hdU5Xzx3DsKXAoo/kKBBM23ngbJmMPzUr1dxhzGc3BuBM1TwxoQScyB0jHk+gOAXY6c0AHTfwMXu/aT7PxLXsAEOQGrFRdDVPxDjbr21W/0f6S4TZORql4gOxMolg8wXWGcN1BTA9JephBfJtyCVanIuMPyKatWCuHuElVvAXQXeDoFmvEAhIO2bz2z09gll5/OGLeWjVee0mvPwzMtteGtaHMCLRcGGST87juIxv5tRIvIA4t9xyguXmJHM9txP8YnvsNJlihJu4K2ugAAAAASUVORK5CYII=');
        }
   
    </style>
</head>
<body>
    <script defer>
        
        // Переменная для данных элемента, из тега "data-*.
        let itemId = undefined;

        // Элемент body текушей страницы.
        let body = document.querySelector("body");

        // Функция добавление нового элемента списка.    
        function addItem(id, itemName, itemData1, itemData2, itemData3) {
            
            // Создаем новый элемент списка.
            let newItem = document.createElement("div");
            newItem.className = "item";
            newItem.dataset.id = id;

            // Формируем структуру элемента списка, заполненного данными.
            newItem.innerHTML = 
            `<div class="itemName">${itemName}</div>
                <div class="itemData">
                    <div>${itemData1}</div>
                    <div>&#x25aa; ${itemData2}</div>
                    <div>&#x25aa; ${itemData3}</div>
                </div>
                <div class="rating">
                    <div class="yellowStar"></div>
            </div>`;

            // Добавляем новый элемент на страницу.
            body.append(newItem);

            // Добавляем событие нажатия на элемент.
            newItem.addEventListener("click", (event) => {

                // Сохраняем данные элемента в переменной для хранения.
                itemId = event.currentTarget.dataset.id;
            });
           
        };

        // Обработка события прокрутки, уведомить платформу 1С о необходимости загрузить новые элементы.
        window.addEventListener("scroll", () => {

            if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight) {
                // console.log("scroll end");
            }            
        });

        // Получение данных элемента, по которому было совершенно нажатие.
        function getItemId() {
            return itemId;
        };
    </script>
</body>
</html>

Пояснение кода:
Существует особенность работы события «scroll» для элементов Поле HTML, был добавлен обработчик события фиксации прокрутки списка до конца, для автоматической загрузки новых элементов списка, но при работе в 1С он не срабатывал, привязка к элементу «document.body», так же не дало результата.

// Обработка события прокрутки, уведомить платформу 1С о необходимости загрузить новые элементы.
window.addEventListener("scroll", () => {

    if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight) {
        // console.log("scroll end");
    }            
});

Изображение звездочки, используется в виде строки, закодированной в Base64. Более подробно можно прочесть по адресу: Data URL и Храните мелкие картинки в CSS.

.yellowStar 
{
    display: inline-block;
    width: 24px;
    height: 24px;
    background-image: url('data:image/png;base64, Закодированная строка);
}

Макет HTML был сверстан с учетом использования атрибута «data-*» тега «div», в котором хранится текущий идентификатор записи, для последующей обработки события нажатия. В текущей версии платформы 1С, не удалось получить на прямую данные из dataset атрибута, видимо ограничение взаимодействие между платформой 1С и web движком «WebKit». Для обхода сложившейся ситуации, на элементы с классом «item», добавлен обработчик нажатия, который получает необходимые данные и сохраняет их в переменной «itemId». Для получения данных добавлена функция «getItemId», которая просто возвращает значение переменной «itemId».

// Переменная для данных элемента, из тега "data-*.
let itemId = undefined;

// Элемент body текушей страницы.
let body = document.querySelector("body");

// Функция добавление нового элемента списка.    
function addItem(id, itemName, itemData1, itemData2, itemData3) {
    
    // Создаем новый элемент списка.
    let newItem = document.createElement("div");
    newItem.className = "item";
    newItem.dataset.id = id;

    // Формируем структуру элемента списка, заполненного данными.
    newItem.innerHTML = 
    `<div class="itemName">${itemName}</div>
        <div class="itemData">
            <div>${itemData1}</div>
            <div>&#x25aa; ${itemData2}</div>
            <div>&#x25aa; ${itemData3}</div>
        </div>
        <div class="rating">
            <div class="yellowStar"></div>
    </div>`;

    // Добавляем новый элемент на страницу.
    body.append(newItem);

    // Добавляем событие нажатия на элемент.
    newItem.addEventListener("click", (event) => {

        // Сохраняем данные элемента в переменной для хранения.
        itemId = event.currentTarget.dataset.id;
    });
    
};

2. Добавлены реквизиты формы.

На форму обработки, добавлены два реквизита «ПолеHTMLСписок» тип строка, вид «Поле HTML документа», и текстовый документ «ТекстовыеДанные», для простого вывода данных элемента списка, при нажатии, а именно идентификатора элемента.

3. Добавлены обработчики событий.

Загрузка макета HTML, осуществляется в процедуре «ПриСозданииНаСервере»:

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

Для элемента формы «ПолеHTMLСписок» добавлены обработчики «ДокументСформирован» и «ПриНажатии», со следующей реализацией:

&НаКлиенте
Процедура ПолеHTMLСписокДокументСформирован(Элемент)
	
	Если НЕ Элементы.ПолеHTMLСписок.Документ.readyState = "complete" Тогда
		Возврат;
 	КонецЕсли;
	
	ОкноHTML = Элементы.ПолеHTMLСписок.Документ.defaultView; 
    Если ОкноHTML = Неопределено Тогда
        Возврат;
    КонецЕсли; 
	
	МассивПродаж = ДанныеПродаж(); 
	Для каждого Продажа Из МассивПродаж Цикл
		
		// addItem(id, itemName, itemData1, itemData2, itemData3); 
		ОкноHTML.addItem(Продажа.ИдентификаторСчетФактуры, Продажа.ВидНоменклатуры, Продажа.ТипКлиента, Продажа.Пол, Продажа.РейтингКлиента);
	
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ПолеHTMLСписокПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	Если ДанныеСобытия.Event.type = "click" И ДанныеСобытия.Element.tagName = "DIV" Тогда
		
		ОкноHTML = Элементы.ПолеHTMLСписок.Документ.defaultView; 
		Если ОкноHTML = Неопределено Тогда
			Возврат;
		КонецЕсли; 
		
		ИдентификаторЭлемента = ОкноHTML.getItemId();
		ТекстовыеДанные.ДобавитьСтроку(ИдентификаторЭлемента);
		
	КонецЕсли;  

КонецПроцедуры

💾 Внешняя обработка ПолеHTMLДокументаСписок.zip.

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

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