Как запустить работу Google Maps в поле HTML формы 1С?

Программирование - Практика программирования

21
Как справиться с передачей события в поле HTML, если надо передать данные. Переход на новую версию Google Maps.

Как запустить работу Google Maps в поле HTML формы 1С?

При изменении версии на новую Google Maps перестала работать обработка 1С, которая отображала карту через HTML поле в InternetExplorer 9.

Как программисту  на JavaScript и 1C эта работа досталась мне.

Как положено в новых браузерах, сделал код вызова события

window.sendEvent = function(eventName, eventData)
{
    var e = document.createEvent('Event');
    e.initEvent('onhelp', false, true); 
    e. eventName = eventName;
    e. eventData= eventData;
    document.dispatchEvent(e);
    return e;
}

 Но этот код никак не хотел выдавать событие onHelp в 1С.

Даже добавил в реестре HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION вызов 11 версии IE.  Этот способ меняет настройки встроенного браузера. Никакого результата. 

Тогда переключил режим браузера в IE10,

<meta http-equiv=""X-UA-Compatible"" content=""IE=10"">

И тогда старый код стал выдавать событие, и заработала карта.

Но надо было решить задачу передачи данных через поля объекта в 1С. Эти поля упорно не передавались. Они просто обрезались при передаче.

Тогда обратил внимание на стандартное поле data , и о радость, data  передавалось в событие onHelp  и вылавливалось обработчиком событий 1С.

Но data было строковым, а мне требовался объект. Посмотрев еще, обнаружил что кроме data в событие передавалось поле dataFld. И оно тоже было строковым. 

Я решил использовать сериализацию, то есть превращение объекта в строку, а потом строки в объект  и  передал таким образом объект  в обработчик события.

Полученный код:

Вначале, в теге <title> надо переключить браузер в режим IE 10 (В IE 9 режиме не работает карта, в IE 11 режиме не работают события):

|<meta http-equiv=""X-UA-Compatible"" content=""IE=10"">

Вызов события с передачей данных из поля HTML в обработчик 1С.  

|window.sendEvent = function(eventName, eventData)
|{
|             var e = document.createEventObject();
|             //var e = document.createEvent('Event');
|             //e.initEvent('onhelp', false, true);
|             e.data = eventName;
|             e.dataFld = JSON.stringify(eventData);
|             //document.dispatchEvent(e);
|             document.body.fireEvent('onhelp', e);
|             return e;
|}

Код обработчика onHelp

Процедура ПолеHTMLДокonhelp(Элемент, e)
    if (e.data="map.ready") then
        Сообщить("Карта готова");
        КартаГотова();
    endif;
   
    if (e.data="message") then
        Сообщить(e.dataFld);
    endif;               

    if (e.data="info.open") then
        eventData=jsonПрочитатьПлатформой(e.dataFld);
        ОписаниеАдресатовДляДома = ПолучитьОписаниеАдресатовПоАдресуДому(eventData.Получить("address"));
        ОписаниеАдресатовДляДома = eventData.Получить("address") + "<br>"+ОписаниеАдресатовДляДома;
        ЭлементыФормы.ПолеHTMLДок.Документ.parentWindow.setInfoWindowContent(ОписаниеАдресатовДляДома);
    endif;
КонецПроцедуры

 

Сервисные функции для обработки JSON на 1С,( взято отсюда //1c-soft.it-terminal.ru/public/551972/) :

Функция jsonПрочитатьПлатформой(Значение)

    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Значение);   

    Результат = Неопределено;
    СформироватьДерево(ЧтениеJSON, Результат);
    ЧтениеJSON.Закрыть(); 

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


Процедура СформироватьДерево(ЧтениеJSON, Дерево)   

    ИмяСвойства = Неопределено;   

    Пока ЧтениеJSON.Прочитать() Цикл
        TипJSON = ЧтениеJSON.ТипТекущегоЗначения;        

        Если TипJSON = ТипЗначенияJSON.НачалоОбъекта
        ИЛИ TипJSON = ТипЗначенияJSON.НачалоМассива Тогда
            НовыйОбъект = ?(TипJSON = ТипЗначенияJSON.НачалоОбъекта, Новый Соответствие, Новый Массив);        

            Если ТипЗнч(Дерево) = Тип("Массив") Тогда
                Дерево.Добавить(НовыйОбъект);
            ИначеЕсли ТипЗнч(Дерево) = Тип("Соответствие") И ЗначениеЗаполнено(ИмяСвойства) Тогда
                Дерево.Вставить(ИмяСвойства, НовыйОбъект);
            КонецЕсли;          

            СформироватьДерево(ЧтениеJSON, НовыйОбъект);           

            Если Дерево = Неопределено Тогда
                Дерево = НовыйОбъект;
            КонецЕсли;
        ИначеЕсли TипJSON = ТипЗначенияJSON.ИмяСвойства Тогда
            ИмяСвойства = ЧтениеJSON.ТекущееЗначение;
        ИначеЕсли TипJSON = ТипЗначенияJSON.Число
        ИЛИ TипJSON = ТипЗначенияJSON.Строка
        ИЛИ TипJSON = ТипЗначенияJSON.Булево
        ИЛИ TипJSON = ТипЗначенияJSON.Null Тогда
            Если ТипЗнч(Дерево) = Тип("Массив") Тогда
                Дерево.Добавить(ЧтениеJSON.ТекущееЗначение);
            ИначеЕсли ТипЗнч(Дерево) = Тип("Соответствие") Тогда
                Дерево.Вставить(ИмяСвойства, ЧтениеJSON.ТекущееЗначение);
            КонецЕсли;
        Иначе
            Возврат;
        КонецЕсли;
    КонецЦикла;   

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

 

21

См. также

Комментарии
Избранное Подписка Сортировка: Древо
1. dsdred 791 27.09.18 08:52 Сейчас в теме
ХМ странно... Вы выложили ссылку на статью (https://infostart.ru/public/551972/) в которой в комментариях написано, что стандартный метод ПрочитатьJSON в разы быстрее работает метода из статьи и автор статьи в комментариях это подтверждает...
Но выбрали все равно более медленный и более громоздкий способ...

//Всего 3 строчки кода
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(e.dataFld);

eventData= ПрочитатьJSON(ЧтениеJSON);
3. Green2 25 27.09.18 11:40 Сейчас в теме
(1)Спасибо за замечание, оказывается эти функции реализуются простой функцией ПрочитатьJSON()
Примененная функция хороша только в одном случае, когда передаются переменные типа Дата. И стандартным способом десерилизацию провести нельзя. Хотя и даже для Дата можно сделать простым способом. Если типы простые, то все решается одной функцией.

Я первый раз делал такую задачу, и заодно изучал работу JSON.
Из за распространенности данного формата в веб приложениях, я думаю, это будет одна из самых востребованных функций.
Например, я сейчас делаю модуль обмена специфической конфигурации 1С с Битрикс 24, и обмен в формате JSON.
4. dsdred 791 27.09.18 14:30 Сейчас в теме
(3)
Спасибо за замечание, оказывается эти функции реализуются простой функцией ПрочитатьJSON()

Не за что. Я просто удивился, что та статья вышла позже моей на 4 дня https://infostart.ru/public/551045/
При этом у меня в примере ПрочитатьJSON()

Примененная функция хороша только в одном случае, когда передаются переменные типа Дата. И стандартным способом десерилизацию провести нельзя. Хотя и даже для Дата можно сделать простым способом. Если типы простые, то все решается одной функцией.

для даты обычно использую типовую функцию из розницы брал

//Получаем дату из входных параметров
Функция ПолучитьДатуВремяИзСтроки(ДатаВремя) Экспорт
	
	Результат = Неопределено;
	ДатаВремя = СтрЗаменить(ДатаВремя, "-", "");
	ДатаВремя = СтрЗаменить(ДатаВремя, ":", "");
	Если СтрДлина(ДатаВремя) - Найти(ДатаВремя, " ") = 5 Тогда // время в формате Ч:ММ:СС
		ДатаВремя = СтрЗаменить(ДатаВремя, " ", "0");
	ИначеЕсли Найти(ДатаВремя, "T") > 0 Тогда //время в формате ГГГГММДДTЧЧММСС
		ДатаВремя = СтрЗаменить(ДатаВремя, "T", "");
	Иначе // время в формате ЧЧ:ММ:СС
		ДатаВремя = СтрЗаменить(ДатаВремя, " ", "");
	КонецЕсли;
	
	ОписаниеТипа = Новый ОписаниеТипов("Дата");
	Результат = ОписаниеТипа.ПривестиЗначение(ДатаВремя);  // дата и время в виде "ГГГГММДДЧЧММСС"
	Если Не ЗначениеЗаполнено(Результат) Тогда
		Результат = ОписаниеТипа.ПривестиЗначение(Лев(ДатаВремя, 8));  // только дата "ГГГГММДД"
	КонецЕсли;

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


Я первый раз делал такую задачу, и заодно изучал работу JSON.
Из за распространенности данного формата в веб приложениях, я думаю, это будет одна из самых востребованных функций.
Например, я сейчас делаю модуль обмена специфической конфигурации 1С с Битрикс 24, и обмен в формате JSON.


Это хорошо, что сами пробуете и делаете. А JSON не только в веб приложениях распространен.
С JSON работаю с 2015, в тот год пришлось много API использовать и в платформе как раз нарисовали поддержку. А так на работе приходится сейчас часто http-сервисы рисовать для вебера, он сам в JSONе просит данные.


П.С. А ниже Вам правильно написали про WebKIT Перевод клиентских приложений для Windows на использование WebKit (оптимизация отображения HTML)
2. alexzhilichev 145 27.09.18 10:58 Сейчас в теме
Потерпите чуть-чуть, и перейдем на WebKit. Должно быть в разы лучше.
5. gubanoff 44 27.09.18 17:04 Сейчас в теме
(0) может знаете решение проблемы не по теме: в управляемом приложении в ПолеHTML 1С не переходит по ссылкам на якори.
|<P><A name=НачалоДокумента>Якорь</A></P>
	|<P></P>
	|<P></P>
	|<P></P>
	|<P>Перейти к якорю</P>

Может есть какое-то решение на javascript?
Прикрепленные файлы:
ТестПереходаПоЯкорюВHTMLДокументе.epf
6. as 03.10.18 09:38 Сейчас в теме
Непонятно почему вы решили, что IE11 не работает.
Я делаю так:
<head>
  <met a http-equiv="X-UA-Compatible" content="IE=11" />
</head>
<body>
  <button id="SentDataButton1c" style="display: none"></button>
 </body>



 function sentData(message) {
    errStr = "";
    success = false;
	try {
		if (parentForm == undefined) {
			SentDataButton1cData = message;
			SentDataButton1c.click();
			success = true;
		}
	}
		catch(e) {
		errStr += e.message;	
	};
    try {
      if (!success) parentForm.sentData(message);
    } catch (e) {
      errStr += e.message;
      alert(errStr);
    };
  };
Показать


При это этот код работает под всеми платформами: win,linux, mac и web(проверял только Chrome).
Из 1С после обработки события доступны переменные объекта ПолеХТМЛ через ВнешнийОбъект

&НаКлиенте
Функция ПолучитьВнешнийОбъектХТМЛ(ПолеХТМЛ) Экспорт

	СисИнфо = Новый СистемнаяИнформация;
	Если Найти(СисИнфо.ТипПлатформы,"Windows") = 0 Тогда
		Возврат ПолеХТМЛ.Документ.defaultView;
	Иначе	
	#Если не ВебКлиент Тогда
		Возврат ПолеХТМЛ.Документ.parentWindow;
	#КонецЕсли
	КонецЕсли;
	Попытка
		Если Найти(СисИнфо.ИнформацияПрограммыПросмотра, "MSIE") = 0 Тогда
			Возврат ПолеХТМЛ.Документ.defaultView;
		Иначе
			Возврат ПолеХТМЛ.Документ.parentWindow;
		КонецЕсли;
	Исключение
		Возврат Неопределено;
	КонецПопытки;

КонецФункции
Показать


Что важно, код продолжит работать после появления WebKit под Windows.
7. Green2 25 03.10.18 12:00 Сейчас в теме
(6)
parentForm

(6)
SentDataButton1cData

Я проанализировал код и не понял, что это за переменные, как они объявляются.
Предположу, что parentForm это document.body?
А SentDataButton1cData это просто определение переменной через var?
8. as 03.10.18 17:50 Сейчас в теме
(7) parentForm это ссылка на форму 1с внутри JS, а SentDataButton1cData просто переменная с данными.
Я заполняю их так:
  var initialized, parentForm;
  var SentDataButton1cData;
  function initialize(thisForm) {
    parentForm = thisForm;
    initialized = true;
  };

initialize вызывается из 1С для инициализации.
Оставьте свое сообщение