September 13, 2012

bitrix.news + ajax filter + костыли

Всем привет! На одном сайте есть комплексный компонент отображающий количество вакансий в одном из филиалов компании. Реализован он так: cверху фильтр с двумя списками - в одном филиалы, в другом должности, внизу список доступных должностей.

Все работало отлично и не требовало вмешательств, но появилась новая задача - обновление списка должностей при переключении радиобаттона по филиалам. Предстояло как то добавить отправку ajax-запроса по onchange у радиобаттонов.

Эта задача достаточно тривиально решается на jquery, но тогда придется написать вручную код для отдачи вакансий. Терять возможность визуальной настройки компонента и плодить еще больше костылей не хотелось и поэтому я решил внедрить отправку ajax в шаблон компонента. При включении в настройках компонента режима ajax битрикс при его отображении заменяет все ссылки и action у форм на сгенерированный js. Подробнее об этом можно почитать здесь.

На странице в которую предстояло внедрить магию скрипт отправки выглядел примерно так:

<form id="arrFilter" ...>

<script>
function _processform_211(){
    var obForm = top.BX('bxajaxid_8ed9f266d80b1b14fc534b07b64da398_211').form;
    top.BX.bind(obForm, 'submit', function() {BX.ajax.submitComponentForm(this, 'comp_8ed9f266d80b1b14fc534b07b64da398')});
    top.BX.removeCustomEvent('onAjaxSuccess', _processform_211);
}
if (top.BX('bxajaxid_8ed9f266d80b1b14fc534b07b64da398_211'))
    _processform_211();
else
    top.BX.addCustomEvent('onAjaxSuccess', _processform_211);
</script>

Отправкой ajax заведует функция BX.ajax.submitComponentForm, но в работе она использует два параметра, если с первым нет проблем, то второй (‘comp_8ed9f266d80b1b14fc534b07b64da398’) генерируется скриптом на лету и отловить его значение в шаблоне фильтра не представляется возможным. Но функция биндится на событие submit, а значит если удастся его сгенерировать то ajax отправится сам. Покопавшись в документации к js я выяснил что очевидная функция form.submit() к использованию не годится ибо заставляет браузер отправить данные, но при этом не генерирует событие DOM submit, а стало быть битриксовый js это событие никак не отловит.

Далее было решено сгенерировать средствами js событие submit которое в свою очередь отловилось бы битриксовым скриптом. Но оказалось что это: a) сложно и б) ненадежно. Ну а потом я додумался до того что если событие DOM генерирует кнопка submit, то нужно как то ее нажать. В итоге я вставил в форму еще один submit с id=“test” и средствами Jquery (он просто уже был подключен в проекте) отправил $(‘#test’).click(). В итоге событие DOM сгенерировалось автоматически и было успешно перехачено битрикосвым js. Ajax сработал как надо! =)

Итак, небольшой код иллюстрирующий наш костыль:

</form>
<form id="arrFilter" ...>
<script>
function _processform_211(){
    var obForm = top.BX('bxajaxid_8ed9f266d80b1b14fc534b07b64da398_211').form;
    top.BX.bind(obForm, 'submit', function() {BX.ajax.submitComponentForm(this, 'comp_8ed9f266d80b1b14fc534b07b64da398')});
    top.BX.removeCustomEvent('onAjaxSuccess', _processform_211);
}
if (top.BX('bxajaxid_8ed9f266d80b1b14fc534b07b64da398_211'))
    _processform_211();
else
    top.BX.addCustomEvent('onAjaxSuccess', _processform_211);
</script>

<input type="submit" id="test" value="start" style="display:none;">

<label><input type="radio" value="1852" name="arrFilter_pp[filial]" onchange="$('#test').click()">Балашиха </label>

В итоге коде появилась лишь одна лишняя строчка и все заработало как надо. Такой вот костыль. Удачи всем!

Другие проекты:

telegram-catalog.top

rhamdeew © 2020