С выходом нового шаблона компонента sale.order.ajax на форумах битрикса разгораются возмущения и недомения. Мол, теперь код всего шаблона на JavaScript и как его кастомизировать непонятно. На самом деле да, код js-скрипта составляет почти семь тысяч строк. Сходу в таком количестве кода, даже хорошо написанного (к сожалению, битрикс этим не балует), соблюдая паттерны программирования, будет непросто.
В этой заметке я покажу способ, как можно кастомизировать основной скрипт логики шаблона оформления заказа (order_ajax.js), не прибегая к его правке. Что нам это даёт? Когда прилетят очередные обновления шаблона, мы просто заменим его и всё. Все наши кастомизации будут работать (в теории).
Итак, поехали!
Кастомизировать будем так, чтобы в оформлении осталось только 2 блока (блока с вводом данных покупателя, а так же выводом самой корзины), вместо 6. Если у нас интернет-магазин маленький, то задача вполне себе реальная.
Чтобы получилось примерно так:
Все махинации сводятся к расширению BX.Sale.OrderAjaxComponent. Ну как, к расширению.. Полноценным расширением это сложно назвать. Так как битрикс в разработке шаблонов (и не только), практически не ориентируется на расширение этих шаблонов своими партнёрами, то нам приходится выкручивать себе яйца и изобретать костыли. По другому это не назвать. Вот зачем нужно было писать объект BX.Sale.OrderAjaxComponent без прототипа?
Ладно, ближе к делу 🙂
Кастомизируем
Создаём файл order_ajax_ext.js в папке с шаблоном компонента sale.order.ajax (там же, где лежит файл order_ajax.js) с содержимым:
(function () { 'use strict'; var initParent = BX.Sale.OrderAjaxComponent.init, getBlockFooterParent = BX.Sale.OrderAjaxComponent.getBlockFooter, editOrderParent = BX.Sale.OrderAjaxComponent.editOrder ; BX.namespace('BX.Sale.OrderAjaxComponentExt'); BX.Sale.OrderAjaxComponentExt = BX.Sale.OrderAjaxComponent; BX.Sale.OrderAjaxComponentExt.init = function (parameters) { initParent.apply(this, arguments); var editSteps = this.orderBlockNode.querySelectorAll('.bx-soa-editstep'), i; for (i in editSteps) { if (editSteps.hasOwnProperty(i)) { BX.remove(editSteps[i]); } } }; BX.Sale.OrderAjaxComponentExt.getBlockFooter = function (node) { var parentNodeSection = BX.findParent(node, {className: 'bx-soa-section'}); getBlockFooterParent.apply(this, arguments); if (/bx-soa-auth|bx-soa-properties|bx-soa-basket/.test(parentNodeSection.id)) { BX.remove(parentNodeSection.querySelector('.pull-left')); BX.remove(parentNodeSection.querySelector('.pull-right')); } }; BX.Sale.OrderAjaxComponentExt.editOrder = function (section) { editOrderParent.apply(this, arguments); var sections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'), i; for (i in sections) { if (sections.hasOwnProperty(i)) { if (!(/bx-soa-auth|bx-soa-properties|bx-soa-basket/.test(sections[i].id))) { sections[i].classList.add('bx-soa-section-hide'); } } } this.show(BX('bx-soa-properties')); this.editActiveBasketBlock(true); this.alignBasketColumns(); if (!this.result.IS_AUTHORIZED) { this.switchOrderSaveButtons(true); } }; BX.Sale.OrderAjaxComponentExt.initFirstSection = function (parameters) { }; })();
Подробнее, что происходит
В отдельных переменных определяем функции-методы родительского BX.Sale.OrderAjaxComponent, чтобы их можно было вызвать в дочерних функциях и не получить ошибку Maximum call stack size exceeded.
Копируем ссылку с BX.Sale.OrderAjaxComponent в BX.Sale.OrderAjaxComponentExt.
В методе BX.Sale.OrderAjaxComponentExt.init вызываем родительский init, следом прибиваем ссылки «изменить» у всех блоков. Они нам не нужны.
В методе BX.Sale.OrderAjaxComponentExt.getBlockFooter прибиваем кнопки «Назад» и «Вперед» у блоков. Они нам тоже не понадобятся — все блоки у нас развёрнуты.
В методе BX.Sale.OrderAjaxComponentExt.editOrder ненужным блокам-секциям добавляем css-класс bx-soa-section-hide. По нему мы и будем скрывать ненужные блоки. А так же в этом методе раскрываем только нужные нам блоки: «Покупатель» и «Товары в заказе».
Метод BX.Sale.OrderAjaxComponentExt.initFirstSection оставляем просто пустым. Если этого не сделать, то у анонимов при попытке оформления будет вываливаться эксепшен, по поводу отсутствия необходимых обязательных полей.
Идем дальше.
Правки шаблона: подключаем наш скрипт и меняем вызов BX.Sale.OrderAjaxComponent на свой
В файле template.php нашего шаблона нового оформления добавляем подключение нашего скрипта order_ajax_ext.js:
После строчки:
$this->addExternalJs($templateFolder.'/order_ajax.js');
добавляем:
$this->addExternalJs($templateFolder.'/order_ajax_ext.js');
А так же в файле template.php меняем все вызовы BX.Sale.OrderAjaxComponent на BX.Sale.OrderAjaxComponentExt
Правки CSS
Ну и не забываем добавить в файл стилей, чтобы ненужные блоки скрылись:
.bx-soa-section-hide { display: none; }
На этом всё. Всегда старайтесь подходить к задачам творчески 🙂