Свойство типа Привязка к карте Google Maps появилось в Битриксе уже давно, аж в 2009 году. Если прокрутить до комментов, можно найти внизу такую проблему:
anya_o 28.05.2010 15:10:53
добрый день! не получается вводить множественные значения этих свойств, пробовала в разных браузерах. у гугла показывается одна карта и несколько еще "загружается" (в эксплорере вообще показывается пустая страница), у яндекса показывается несколько строк для координат но сохраняется только верхняя. это будет исправлено?
Надо сказать это не единственное упоминание, встречаются и другие. Проблема судя по всему до сих пор не исправлена, хотя отзывы от пользователей с просьбой устранить баг были и в 2011 году. Я проблему решил и предлагаю почитать об этом далее.
Итак, делаем множественное свойство "Привязка к карте Google Maps", заходим в создание элемента и... свойство не работает, т.к. все карты являются простыми картинками. В js-отладчике явственно видна ошибка от google js-api указывающее на дублирующее подключение скрипта карт. Явная ошибка. Лезем в ядро (пока только посмотреть). В /bitrix/modules/fileman/properties.php обнаруживаем что за вывод карт отвечает компонент bitrix:map.google.system. Лезем туда. В коде компонента оказывается мало полезного, зато в шаблоне встречается такой вот код:function BXMapLoader_(MAP_KEY)
{
if (null == window.bGoogleMapScriptsLoaded)
{
if (window.google && window.google.maps)
{
window.bGoogleMapScriptsLoaded = true;
BX.ready(init_);
}
else
{
BX.loadScript(
'http://www.google.com/jsapi?rnd=' + Math.random(),
function () {
if (BX.browser.IsIE())
setTimeout("window.google.load('maps', , {callback: init_, other_params: 'sensor=false&language='})", 1000);
else
google.load('maps', , {callback: init_, other_params: 'sensor=false&language='});
}
);
}
}
else
{
init_();
}
}
Невооружённым глазом видно что битрикс загружает гугловый js-api, а когда он подгрузится вызывает подгрузку гугл-карт. У гугл-карт стоит callback-вызов на инициализацию карты (т.е. когда скрипт гугл-карт подгрузится пустые блоки google-карт заменятся этим вызовом на нормальную карту).
Что же происходит когда мы делаем это свойство множественным? Битрикс подключает этот компонент несколько раз. Несколько раз подключается и этот шаблон. Несколько раз грузится google js api. Несколько раз вызывается инициализация (что само по себе вроде аварию не создаёт, но неправильно). Чтобы устранить дублирование загрузки, в код поставлено несколько "костылей", посмотрим код:
window.arGoogleMapCallbacks = {};
function initAllGoogleMaps()
{
for(var i in window.arGoogleMapCallbacks)
{
window.arGoogleMapCallbacks[i]();
}
}
function BXMapLoader_(MAP_KEY)
{
if (null == window.bGoogleMapScriptsLoaded)
{
if (window.google && window.google.maps)
{
window.bGoogleMapScriptsLoaded = true;
BX.ready(init_);
}
else
{
BX.loadScript(
'http://www.google.com/jsapi?rnd=' + Math.random(),
function () {
if (BX.browser.IsIE())
setTimeout("window.google.load('maps', , {callback: init_, other_params: 'sensor=false&language='})", 1000);
else
google.load('maps', , {callback: initAllGoogleMaps, other_params: 'sensor=false&language='});
}
);
window.arGoogleMapCallbacks['init_'] = init_;
}
}
else
{
init_();
}
}
Внимание! Данные правки можно сделать без вмешательства в ядро, достаточно создать свой шаблон в папке /bitrix/templates/.default/components/bitrix/map.google.system/.default/
Логика поправки такова - грузим код подгрузки google js-api (и его карт) лишь 1 раз, сколько бы не подключался шаблон. В callback'е указываем свою js-функцию, которая призвана запустить не как ранее инициализацию одного блока карт, а инициализацию всех блоков карт на странице. Для того чтобы наша функция могла инициализировать все нужные карты создаём дополнительный js-массив arGoogleMapCallbacks в который помещаем все что ранее передавалось в callback. Вот казалось бы и все, ан нет... Следующая проблема оказывается в том в /bitrix/modules/fileman/properties.php уникальный идентификатор блока карты генерируется так:
$MAP_ID = 'map_google_'.$arProperty['CODE'].'_'.$arProperty['ID'];
Так, свойство у нас одно. Код у него один, ID один. Значит все блоки одного свойства будут иметь одинаковый MAP_ID. А так как инициализация идёт по определённому ID будет инициализирована только первая карта (хорошо что хоть какая-то). Исправить это можно "подмешав" в MAP_ID соль:
$MAP_ID = 'map_google_'.randString().'_'.$arProperty['CODE'].'_'.$arProperty['ID']; // multiple maps bugfix
Увы, эта правка является не рекомендуемой, так делается в ядре продукта (напомню, это файл /bitrix/modules/fileman/properties.php). Но другого варианта я не нашёл. Можно так же создать своё собственное свойство, скопировав весь стандартный код и внеся нужные правки, но я не стал.
Для ознакомления с кодом решения выкладываю готовые файлы. Но все же из за разницы версий рекомендую делать правки мануально.
Что ж, вот и все. Надеюсь помог. Будем ждать нативную правку от 1С-Битрикс.
Сделал все как вы написали. Ничего не помогло. За исключением того, что исчезла ошибка в файрбаге, которая была связана с вызовом скрипта api. Остальные карты как были с надписью "загрузка карты" так и остались. Задолбался уже. Дебильный битрикс :(
ОтветитьУдалить