Что делать, если необходим богатый интерфейс, а управляемые формы нам его не могут обеспечить? Использовать HTML и JavaScript. В статье рассмотрено взаимодействие кода 1С и JavaScript, работающее на любой платформе: толстый, тонкий и веб-клиент, под Windows и Linux.
На текущий момент штатные средства 1С в управляемых формах не могут в полной мере удовлетворить потребность в богатом и отзывчивом интерфейсе. Ведь, по словам разработчиков платформы, управляемые формы призваны обеспечить быструю и эффективную разработку бизнес-логики приложения, с некоторым ущербом интерфейсу. Для абсолютного большинства ситуаций это верный подход, но есть случаи, когда необходимо и то, и другое.
Решением является использование HTML и JavaScript.
Прелагается решение, которое работает как в тонком, так и в веб-клиенте. Под Windows и Linux.
Примечание: при упоминании работоспособности в тонком клиенте, также подразумевается работоспособность и в толстом клиенте (управляемое приложение).
Вызов методов языка JavaScript из кода 1С.
Методы JavaScript могут быть вызваны из 1C так:
<Окно документа>.funcName(funcArgs);
<Окно документа>.varName;
Элементы.ПолеHTMLДокумента.Документ.parentWindow
Элементы.ПолеHTMLДокумента.Документ.defaultView
&НаКлиенте
Перем ДокументПервогоБраузера;
&НаКлиенте
Перем ОкноПервогоБраузера;
&НаКлиенте
Процедура ПервыйБраузерДокументСформирован(Элемент)
// Сохранение элементов document и window в переменные модуля формы,
// для последующего быстрого доступа к элементам и функциям.
ДокументПервогоБраузера = Элемент.Документ;
ОкноПервогоБраузера = ДокументПервогоБраузера.parentWindow; // IE
Если ОкноПервогоБраузера = Неопределено Тогда
ОкноПервогоБраузера = ДокументПервогоБраузера.defaultView; // Прочие браузеры
КонецЕсли;
ОкноПервогоБраузера.createButtons(МассивКнопокПервогоБраузера);
КонецПроцедуры
&НаКлиенте
Процедура СоздатьКнопки(Команда)
МассивКнопок = Новый Массив;
...
Для Сч = 1 По КоличествоКнопок Цикл
...
СтруктураКнопки = Новый Структура;
СтруктураКнопки.Вставить("Заголовок", ЗаголовокКнопки);
СтруктураКнопки.Вставить("ИмяКоманды", ИмяКоманды);
СтруктураКнопки.Вставить("РазмерТекста", РазмерТекста);
СтруктураКнопки.Вставить("ЦветТекста", ЦветТекста);
МассивКнопок.Добавить(СтруктураКнопки);
КонецЦикла;
ОкноПервогоБраузера.createButtons(МассивКнопок);
КонецПроцедуры
function createButtons(buttonsArray)
{
var buttonsCount = buttonsArray.Количество(); // Доступны методы и свойства массива 1С
for(var i = 0; i < buttonsCount; i++)
{
ПараметрыКнопки = buttonsArray.Получить(i);
var btn = document.createElement('div');
btn.id = ПараметрыКнопки.ИмяКоманды;
btn.innerText = ПараметрыКнопки.Заголовок;
btn.style.fontSize = ПараметрыКнопки.РазмерТекста;
btn.style.color = ПараметрыКнопки.ЦветТекста;
container.appendChild(btn);
}
}
&НаКлиенте
Функция СериализоватьВJSON(СериализуемыйОбъект)
#Если ВебКлиент Тогда
СтрокаJSON = СериализоватьВJSONНаСервере(СериализуемыйОбъект);
#Иначе
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
НастройкиСериализации = Новый НастройкиСериализацииJSON();
НастройкиСериализации.СериализовыватьМассивыКакОбъекты = Ложь;
ЗаписатьJSON(ЗаписьJSON, СериализуемыйОбъект, НастройкиСериализации, "ПреобразованиеВJSON", ЭтотОбъект);
СтрокаJSON = ЗаписьJSON.Закрыть();
#КонецЕсли
Возврат СтрокаJSON;
КонецФункции
&НаСервереБезКонтекста
Функция СериализоватьВJSONНаСервере(СериализуемыйОбъект)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
НастройкиСериализации = Новый НастройкиСериализацииJSON();
НастройкиСериализации.СериализовыватьМассивыКакОбъекты = Ложь;
ЗаписатьJSON(ЗаписьJSON, СериализуемыйОбъект);
// ЗаписатьJSON(ЗаписьJSON, СериализуемыйОбъект, НастройкиСериализации, "ПреобразованиеВJSON", ЭтотОбъект);
//
// ЭтотОбъект недоступнен в безконтекстном вызове, поэтому нужно либо поместтить эту функцию в общий модуль,
// либо изменить директиву компиляции в &НаСервере
СтрокаJSON = ЗаписьJSON.Закрыть();
Возврат СтрокаJSON;
КонецФункции
&НаКлиентеНаСервереБезКонтекста
Функция ПреобразованиеВJSON(Свойство, Значение, ДополнительныеПараметры, Отказ) Экспорт
// Данная функция вызывается для всех свойств, тип которых не поддерживает преобразование в формат JSON напрямую.
// Они нам не нужны, поэтому всегда отказ от их записи.
Отказ = Истина;
// Можно сделать преобразование в строку.
// Значение = Строка(Значение);
// Возврат Значение;
КонецФункции
&НаКлиенте
Функция ДесериализоватьИзJSON(СтрокаJSON)
#Если ВебКлиент Тогда
ДесериализованныйОбъект = ДесериализоватьИзJSONНаСервере(СтрокаJSON);
#Иначе
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
ДесериализованныйОбъект = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
#КонецЕсли
Возврат ДесериализованныйОбъект;
КонецФункции
&НаСервереБезКонтекста
Функция ДесериализоватьИзJSONНаСервере(СтрокаJSON)
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
ДесериализованныйОбъект = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Возврат ДесериализованныйОбъект;
КонецФункции
JSONМассивКнопокПервогоБраузера = СериализоватьВJSON(МассивКнопокПервогоБраузера);
ОкноПервогоБраузера.createButtons(JSONМассивКнопокПервогоБраузера);
function createButtonsWithJSON(buttonsData)
{
buttonsData = JSON.parse(buttonsData);
for(var i in buttonsData)
{
ПараметрыКнопки = buttonsData[i];
var btn = document.createElement('li');
btn.id = ПараметрыКнопки.ИмяКоманды;
...
}
}
&НаКлиенте
Процедура ПолучитьОбъектИзJavaScript(Команда)
JSONСтруктураОтвета = ОкноПервогоБраузера.getDataFromJavaScript("");
// Нужно передать любой параметр, например пустую строку, иначе функция не выполняется,
// а переменной принимающей результат присваивается ссылка на эту функцию (COMОбъект).
СтруктураОтвета = ДесериализоватьИзJSON(JSONСтруктураОтвета);
Для Каждого КлючИЗначение Из СтруктураОтвета Цикл
Сообщить("Ключ: " + КлючИЗначение.Ключ + " Значение: " + КлючИЗначение.Значение);
КонецЦикла;
КонецПроцедуры
function getDataFromJavaScript()
{
var arr = []; // Массив
arr.push(555);
arr.push("Строка в массиве");
var obj = {}; // Объект (структура)
obj["Ключ1"] = "Пробная строка";
obj["Ключ2"] = 7777;
obj["Ключ3"] = true;
obj["Ключ4"] = arr;
return JSON.stringify(obj);
}
// В документе html, в теге script объявляем глобальную переменную.
var externalForm = null;
var timer = null;
var counter = 0;
function startTimer()
{
alert(externalForm.ПеременнаяМодуля);
timer = setInterval(function()
{
externalForm.МетодВызываемыйИзJavaScript("Значение переменной conunter: " + counter++);
}, 1000);
}
function stopTimer()
{
clearInterval(timer);
}
&НаКлиенте
Перем ПеременнаяМодуля Экспорт;
&НаКлиенте
Процедура ПриОткрытии(Отказ)
...
ПеременнаяМодуля = "Значение переменной модуля";
КонецПроцедуры
&НаКлиенте
Процедура ПервыйБраузерДокументСформирован(Элемент)
...
ОкноПервогоБраузера.externalForm = ЭтаФорма;
КонецПроцедуры
&НаКлиенте
Процедура ЗапуститьТаймер(Команда)
ОкноПервогоБраузера.startTimer();
КонецПроцедуры
&НаКлиенте
Процедура ОстановитьТаймер(Команда)
ОкноПервогоБраузера.stopTimer();
КонецПроцедуры
&НаКлиенте
Процедура МетодВызываемыйИзJavaScript(Данные) Экспорт
Сообщить(Данные);
КонецПроцедуры
var interactionVariable = null;
<button id="interactionButton" style="display: none">Кнопка взаимодействия</button>
interactionVariable = "МетодВызываемыйИзJavaScript через interactionButton. Значение переменной conunter: " + counter;
interactionButton.click();
&НаКлиенте
Процедура ПервыйБраузерПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
НажатыйЭлемент = ДанныеСобытия.Element;
Если НажатыйЭлемент.id = "interactionButton" Тогда
МетодВызываемыйИзJavaScript(ОкноПервогоБраузера.interactionVariable);
// Или Заглушка = Вычислить(ОкноПервогоБраузера.interactionVariable + "()");
// Поле для фантазии большое
КонецЕсли;
КонецПроцедуры
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua