Проблема внедрения верстки в компонент оформления заказа заключается в том, что html код здесь создается динамически на лету с помощью javascript кода, написанного на библиотеке BX - собственной разработке компании 1С-Битрикс.
Итак, мы копируем шаблон компонента в свой шаблон сайта в папке local и открываем template.php. Здесь мы увидим только заготовки блоков заказа. Да мы можем их менять местами друг с другом, но при этом дизайн самих полей не изменится, изменить порядок полей здесь мы не можем.
Вся верстка полей создается динамически и обоснованно этот тем, что блоки зависят друг от друга. Доставка зависит от местоположения - то есть города покупателя, способ оплаты может быть привязан к определенной службе доставке. Также можно настроить, какие именно поля заполнять в зависимости от разных способов доставки или оплаты.
То есть оформление заказа происходит поэтапно, хоть и на одной странице, и каждый блок формируется снова при изменении данных предыдущего блока. Но заказчики хотят видеть простую и понятную форму оформления заказа со всеми полями сразу, хотя она и будет длинной и не будет входить в один экран монитора или телефона.
Поэтому нам надо:
Переставить блоки как в верстке
убрать скрытие блоков и кнопки перемещения между блоками
перенести поля из одного блока в другой по верстке
добавить верстку в блоки и поля - классы стилей, дополнительные div, label
проверить работоспособность оформления заказа
исправить обработчики событий, если они не реагируют на новую верстку
протестировать разные варианты оформления заказа
В файле template.php блоки заказа отмечены комментариями:
<!-- BASKET ITEMS BLOCK --> - корзина заказа - таблица товаров
<!-- REGION BLOCK --> - выбор типа плательщика и ввод местоположения - города покупателя
<!-- DELIVERY BLOCK --> выбор службы доставки
<!-- PAY SYSTEMS BLOCK --> выбор способа оплаты
<!-- BUYER PROPS BLOCK --> форма с полями для ввода данных покупателя
<!-- ORDER SAVE BLOCK --> итог и кнопка подтверждения заказа
Так как нам надо сделать все блоки открытым сразу, то кнопки далее или изменить под каждым блоком нам не нужны, можно удалить в каждом блоке код:
<div class="col-xs-12 col-sm-3 text-right"><a href="javascript:void(0)" class="bx-soa-editstep"><?=$arParams['MESS_EDIT']?></a></div>
Переставляем блоки как нужно по верстке и больше ничего в этом файле мы сделать не можем. далее находим в шаблоне файл order_ajax.js
Рассмотрим его логику:
Создается класс BX.Sale.OrderAjaxComponent, объект которого потом будет создан в template.php
При создании объекта этого класса будет вызвана функция init и в ней будут вызываться функции для заполнения блоков.
Первую интересную функцию мы видим
initFirstSection: function() {
var firstSection = this.orderBlockNode.querySelector('.bx-soa-section.bx-active');
/*BX.addClass(firstSection, 'bx-selected');*/
this.activeSectionId = firstSection.id;
},
вторую строчку надо закомментировать, чтобы все блоки были активны, а не только первый.
Далее обратим внимание на функцию this.editOrder();
Во-первых, надо удалить код, который скрывает блок доставки, если доставки выдали ошибки вычислений:
/*if (this.result.DELIVERY.length > 0) {
BX.addClass(this.deliveryBlockNode, 'bx-active');
this.deliveryBlockNode.removeAttribute('style');
}
else
{
BX.removeClass(this.deliveryBlockNode, 'bx-active');
this.deliveryBlockNode.style.display = 'none';
}*/
Затем в этой функции вызывается создание каждого блока в цикле:
var sections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'), i; for (i in sections)
{
if (sections.hasOwnProperty(i))
{
this.editSection(sections[i]);
}
}
Смотрим функцию this.editSection(sections[i]);
Во-первых уберем проверку, что если в настройках компонента выключена галочка "регистрировать вместе с оформлением заказа", то будет предложено сначала авторизоваться, а все другие блоки будут скрыты.
if (this.result.SHOW_AUTH && section.id != this.authBlockNode.id && section.id != this.basketBlockNode.id)
section.style.display = 'none';
else if (section.id != this.pickUpBlockNode.id)
section.style.display = '';
Во-вторых, видим что проверяется, активен ли блок var active = section.id == this.activeSectionId,
Нам надо, чтобы все блоки были активны, поэтому заменяем этот код на var active = true,
Далее отключаем реагирование на клик по заголовку блока:
Именно в этих функциях создаются поля каждого блока.
Рассмотрим как перенести поля ФИО, Телефон, E-mail в первый блок между выбором типа плательщика и вводом местоположения.
Первый блок создается функцией this.editRegionBlock(active);
А поля для данных покупателя создаются в функции this.editPropsBlock(active); предлагаю перенести выбор плательщика в блок полей данных покупателя и поставить этот блок первым в template.php.
Поэтому идем разбираться сначала в функции this.editRegionBlock(active);
А в этой функции есть два варианта дальнейшего развития событий, либо наш блок открыт, либо скрыт. Все зависит от активности блока. поэтому в нашем случае остается один вариант - это вызов функции this.editActiveRegionBlock(true);
И вот только здесь мы наконец-то видим селекторы по верстке. Во-первых, получаем узел верстки, которую мы будем заполнять:
Верстка создается на Bootstrap:
Далее видим вызов функции для создания радио кнопок выбора типа плательщика:
В этой функции мы и добавляем свою верстку или классы стилей, чтоб стилизовать радио-кнопки.
Перенесем эти вызовы в функцию для блока полей данных. Смотрим this.editPropsBlock(active);
В начале функции все тоже самое, но для блока полей данных покупателя.
После создания получения заготовки под контент по селектору propsContent = node.querySelector('.bx-soa-section-content');
Добавляем в него наши радио-кнопки типов плательщиков
this.getPersonTypeControl(propsContent);
По моей верстке надо разделить блок тип плательщика и данных покупателя, поэтому здесь же добавляем заголовок для данных покупателя:
И далее переходим к функции this.editPropsItems(propsNode);, где добавляются все свойства заказа.
Из нее мы заберем такие поля как индекс, адрес доставки, чтобы добавить их в блоке местоположения, после поля города.
В этой функции мы видим, что создается такой объект массив groupIterator = this.propertyCollection.getGroupIterator() - это как раз все свойства заказа для выбранного типа плательщика.
Поэтому поставить заполнение полей раньше типа плательщика не правильно.
и далее идет такой цикл, в котором при переборе всех свойств делается исключение для свойств - город, местоположение и индекс. Вот это мы и используем.
Залогируем с помощью функции console.log( groupIterator); - увидим, какие параметры имеют наши свойства и уберем из вывода в цикле адрес доставки или поля улица, дом, квартира и т.д.
Создадим массив с ID свойств, которые нужны для вывода в блоке данных покупателя:
Как видим в методе this.getPropertyRowNode(property, propsItemsContainer, false); создается само поле для ввода значения.
В этой функции мы можем изменить верстку и добавить свои классы для стилизации поля.
Рассмотрим подробнее эту функцию:
Здесь создается div, который мы можем дополнить своей версткой.
и далее по типу поля вызываются отдельные методы
В случае с полями данных, это обычные текстовые поля, поэтому разберем подробнее метод: this.insertStringProperty(property, propsItemNode, disabled);
В данной функции input уже существует, он в нашей переменной property, мы его добавляем в созданный div - propsItemNode,
и здесь же можем изменить параметры, для этого добавим такой цикл для соответствия тегов input нашей верстке.
На самом деле здесь обрабатывается один input.
А теперь вернемся в метод this.editActiveRegionBlock(true); и добавим там поля адреса доставки:
После this.getDeliveryLocationInput(regionNodeCol); regionNode.appendChild(regionNodeCol);
добавляем код, аналогичный коду в полях данных покупателя, но только в массиве свойств заказа выбраны свойства адреса доставки для физ и юр лиц.
Итак поля мы переставили, теперь рассмотрим стилизацию блоков доставки и оплаты:
За их наполнение отвечают функции this.editDeliveryBlock(active); и this.editPaySystemBlock(active);
находим в них добавление чекбоксов и скрываем лишний контент, например картинку и блок описания. Блок описания удалять нельзя, чтоб не искать, где он заполняется при выборе другого способа оплаты и доставки.
Расскажите свои случаи внедрения верстки в компонент оформления заказа в комментариях. Задавайте вопросы по сложностям внедрения верстки, постараюсь помочь. Буду благодарна, если при использовании этой статьи напишите мне комментарий. Можете даже указать, для какого магазина вам пригодилась моя статья.