При разработке пользовательских интерфейсов в 1С с использованием HTML часто возникает задача интеграции веб-технологий непосредственно в формы. Одной из таких задач является реализация механизма Drag-and-Drop (перетаскивание файлов) с рабочего стола или из папки операционной системы прямо в поле HTML документа на форме 1С. Казалось бы, стандартный HTML5 предоставляет для этого все необходимые события, однако на практике разработчики сталкиваются с тем, что встроенный в 1С браузер (WebKit) перехватывает событие и просто открывает файл вместо того, чтобы передать управление вашему скрипту.
Давайте подробно разберем, почему возникает эта проблема, и рассмотрим рабочее решение, которое позволит вам корректно обрабатывать перетаскивание внешних файлов.
Рассмотрим ситуацию, с которой мы сталкиваемся. У нас есть форма, на ней размещен реквизит типа Строка или, что чаще, элемент формы связанный с типом ПолеHTMLДокумента. Этот элемент обладает огромным потенциалом, позволяя реализовать универсальный ввод на WEB клиенте, однако при его использовании мы пишем стандартный HTML-код с обработчиками ondrop и ondragover. Если открыть этот HTML в обычном браузере (Chrome, Firefox), все работает: при перетаскивании файла срабатывает скрипт. Но внутри 1С происходит следующее:
Замечено интересное поведение: если сначала выделить какой-то элемент внутри самого поля HTML и перетащить его "сам в себя", то механизм Drag-and-Drop "просыпается", и после этого внешние файлы начинают приниматься корректно. Это связано с инициализацией фокуса и контекста браузерного движка внутри окна 1С.
Однако заставлять пользователя делать лишние движения — плохой тон. Нам нужно решение, которое работает сразу при открытии формы.
Наиболее эффективным и стабильным способом заставить поле HTML документа в 1С принимать внешние события перетаскивания является использование атрибута contenteditable. Этот атрибут сообщает браузеру, что содержимое элемента может быть отредактировано пользователем. В этом режиме браузер активирует расширенные механизмы взаимодействия, включая нативную обработку перетаскивания.
Давайте рассмотрим пример кода, который необходимо разместить в модуле формы. Мы будем формировать HTML-код программно при создании формы на сервере.
В обработчике события ПриСозданииНаСервере сформируем строку с HTML-контентом:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Формируем HTML с CSS стилями и JavaScript обработчиками
ПолеHTML = "<html>
| <style>
| .dragndrop {
| width: 100%;
| height: 100%;
| border: 3px solid orange; /* Визуально выделяем зону */
| padding: 30px;
| box-sizing: border-box; /* Важно для корректных отступов */
| text-align: center;
| background: cornsilk;
| display: flex;
| align-items: center;
| justify-content: center;
| }
| </style>
| <head></head>
| <body>
| <!-- Ключевой момент: атрибуты contenteditable и draggable -->
| <div class=""dragndrop""
| ondrop=""drop(event)""
| draggable=""true""
| contenteditable=""true"">
| Кидай файлы сюда!
| </div>
|
| <script>
| // Функция обработки сброса
| function drop(ev) {
| ev.preventDefault(); // Останавливаем открытие файла
| ev.stopPropagation();
| alert(""Файл успешно перетащен!"");
| // Здесь можно добавить логику передачи данных в 1С
| }
|
| // Предотвращаем стандартное поведение при наведении
| document.body.ondragover = function(ev) {
| ev.preventDefault();
| return false;
| };
| </script>
| </body>
|</html>";
КонецПроцедуры
Давайте проанализируем, почему этот код работает, в отличие от стандартной разметки.
dragover. Если этого не сделать (не вызвать event.preventDefault()), браузер может решить, что сброс в это место невозможен, или попытаться открыть ссылку/файл самостоятельно. В примере выше мы перехватываем это событие на уровне document.body.contenteditable помогает движку правильно инициализировать подсистему Drag-and-Drop.В процессе обсуждения данной темы часто возникает путаница с методом preventDefault(). Давайте проясним ситуацию.
В стандартном HTML5 Drag-and-Drop API:
preventDefault(), чтобы разрешить сброс (Drop). По умолчанию сброс запрещен.preventDefault(), чтобы браузер не открыл файл как картинку или PDF в том же окне.Однако при использовании contenteditable поведение может незначительно меняться. Некоторые разработчики отмечают, что удаление обработчика dragover иногда "чинит" ситуацию, но это скорее исключение или особенность конкретной версии платформы. Мы рекомендуем придерживаться стандарта и явно отменять стандартные действия браузера, чтобы код был предсказуемым.
Приведенный выше пример показывает alert, что подтверждает факт срабатывания события. Чтобы реально обработать файл в 1С, нам нужно усовершенствовать JavaScript функцию drop(ev).
Помните о безопасности: современные браузеры (и WebKit в 1С) не дают полный путь к файлу на диске пользователя (вы увидите что-то вроде C:\fakepath\file.txt). Чтобы передать файл в базу 1С, нам нужно прочитать его содержимое с помощью FileReader внутри JavaScript и передать его, например, как Base64 строку. Этот подход во многом схож с тем, как реализуется отображение картинки из буфера обмена.
Рассмотрим пример расширения функции drop:
function drop(ev) {
ev.preventDefault();
if (ev.dataTransfer.files.length > 0) {
var file = ev.dataTransfer.files[0];
var reader = new FileReader();
reader.onload = function(event) {
// Получаем содержимое файла в base64
var fileData = event.target.result;
// Отправляем событие в 1С
// В 1С его нужно ловить в процедуре ПриНажатии (для старых версий)
// или через специальные методы взаимодействия
var hiddenButton = document.getElementById('btn1c');
// Логика передачи данных зависит от метода интеграции
};
reader.readAsDataURL(file);
}
}
Для более сложной логики можно использовать подходы, применяемые при использовании 1С + JavaScript для расширения интерактивных функций.
Чтобы пользователь понимал, куда именно нужно бросать файлы, используйте CSS. В примере мы использовали класс .dragndrop. Полезно также менять стиль при наведении курсора с файлом (событие dragenter), например, подсвечивать рамку другим цветом. Если же вам необходимо работать с изображениями, полученными не локально, а из интернета, можно рассмотреть варианты добавления картинок по внешним ссылкам.
Используя этот подход с contenteditable, вы сможете создать интуитивно понятный интерфейс для пользователей, позволяя им загружать файлы в 1С простым перетаскиванием, без необходимости нажимать кнопки "Загрузить" и искать файлы через диалоговые окна.