Полезности для sale.order.ajax

Полезности для sale.order.ajax

3636
15.02.2017

Данный пост будет посвящено новому компоненту sale.order.ajax и его шаблоны с js-файлом на 7,5+ тыс. строк. Пост будет собирательным и обновляемым - все, что буду находить в сети, и буду считать интересным и полезным - пуду публиковать тут.

С переходом битрикса на новое ядро, D7 для многих разработчиков начались непростые времена. С одной стороны, новое ядро предназначено для ускорения работы сайтов, с другой стороны, многие механизмы, отлично работавшие на старом ядре, перестали работать.

Компонент bitrx:sale.order.ajax был полностью переработан под использование в новом ядре. В том числе был полностью переработан и шаблон данного компонента. 

Вся логика отрисовки шаблона нового компонента возложена на клиентскую часть и выполняется через файл order_ajax.js (более 7700 строк некомментированного кода:().

Юрий Волошин на форуме разработчиков писал: 

Т.к. "отрисовка" в новом шаблоне происходит через js, кастомизировать следует файл order_ajax.js. 

 У каждого блока существует два состояния - активное и скрытое.

 Активная секция должна всегда находиться в DOM на странице, т.к. в ней находятся нужные нам input'ы для рассчета заказа. Неактивный блок формируется на основе активного, и его нахождение на странице не обязательно. 

 Основной метод - это editOrder, который вызывает редактирование каждого блока (секции - editSection). editSection - определяет текущую активность блока и вызывает конкретный метод для конкретного блока, напр. для блока оплат - editPaySystemBlock. 

 Если блок активен - в видимой части отрисовывается выбор платежных систем (editActivePaySystemBlock - на отрисовку пс можно повлиять здесь), если блок неактивен - editFadePaySystemBlock, который в свою очередь вызовет отрисовку в скрытой области на странице блока с платежными системами, и на основе его сформирует в видимой части информацию о выбранной пс (скрытый/пройденный шаг). 

Это как "в общем" работает js и как его можно кастомизировать.  

Можно добавить, что расположение блоков можно поменять в файле template.php (блоки выделены комментариями)

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

Вот несколько решений конкретных задач кастомизации шаблона компонента.

Определение местоположения пользователя в автоматическом режиме

Стоит задача: Определять местоположение пользователя, например, по геотаргетингу, или как-то еще - не важно. Факто в том, что в куках у пользователя уже установлен город. Как передать этот город в новый компонент? На форуме разработчиков было предложено решение:

use Bitrix\Main\EventManager; 
$eventManager = EventManager::getInstance();
$eventManager->addEventHandler("sale", "OnSaleComponentOrderProperties", Array("Example", "OnSaleComponentOrderProperties"));

class Example
{
   /**
   * У меня по условию задачи известны ID и NAME местоположения
   */
   static $curCityId = XX;  // числовое значение идентификатора местоположения
   static $curCityName = 'Название города';
   
   /**
   * ID свойств заказа   
   */
   const PROP_LOCATION = 6; 
   const PROP_ZIP = 4; 
   const PROP_LOCATION_NAME = 5;


   static function OnSaleComponentOrderProperties(&$arFields)
   {
      $rsLocaction = CSaleLocation::GetLocationZIP(self::$curCityId); 
      $arLocation = $rsLocaction->Fetch(); 
      $arFields['ORDER_PROP'][self::PROP_ZIP] = $arLocation['ZIP'];
      $arFields['ORDER_PROP'][self::PROP_LOCATION_NAME] = self::$curCityName;
      $arFields['ORDER_PROP'][self::PROP_LOCATION] = CSaleLocation::getLocationCODEbyID(self::$curCityId);
   }
}

А вот такая модификация позволяет определить местоположение только по названию города:

class Example {
   static function OnSaleComponentOrderProperties(&$arFields)
   {
      static $curCityName = 'Название города';
      const PROP_LOCATION = 6;  // - Идентификатор свойства с местоположением
      static function OnSaleComponentOrderProperties(&$arFields)
      {
         $res = Bitrix\Sale\Location\LocationTable::getList(array(
         'filter' => array('=NAME.NAME' => self::$curCityName, '=NAME.LANGUAGE_ID' => LANGUAGE_ID),
         'select' => array('CODE' => 'CODE', 'NAME_RU' => 'NAME.NAME', 'TYPE_CODE' => 'TYPE.CODE') //'*', 
         ));
         while($item = $res->fetch())
         {            
            $code = $item["CODE"];
         }
         $arFields['ORDER_PROP'][self::PROP_LOCATION] = $code;
      }
   }
}

Скрыть какое-то свойство

Если необходимо скрыть какое-то свойство, например, свойство индекс - задать значение по умолчанию и не показывать пользователям это поле, то можно внести корректировку в JS. В функции getPropertyRowNode после switch (propertyType) добавляем скрытие данного свойства:

if(property.getId()==6){// идентификатор скрываемого свойства
   var addressInput=propsItemNode.querySelector('textarea');
   propsItemNode.style='display:none;';
   addressInput.value='нужное значение';
}

Исключить из показа нулевой цены за доставку

Очень распространена ситуация, когда при покупке в интернет-магазине пользователь оплачивает именно товар, а доставку оплачивает уже непосредственно транспортной компании. Но если поставить стоимость доставки равной нулю, то визуально будет выглядеть так, что доставка пользователю ничего не будет стоить, что не корректно. Для исключения такой ситуации можно просто скрыть этот ноль из выдачи. Для этого нужно внести небольшие правки в файл order_ajax.js шаблона.

В функции getDeliveryPriceNodes: function(delivery) в блоке "else" заменяем. Вместо:

priceNodesArray = [delivery.PRICE_FORMATED];

пишем:

if(delivery.PRICE>0)
					priceNodesArray = [delivery.PRICE_FORMATED];

Так мы спрячем нулевую цену из свернутого блока с выбранной доставкой.

Дальше нужно скрыть нули в списке служб доставки. Для этого в функции createDeliveryItem: function(item) делаем строгую проверку на ноль. Вместо:

if (item.PRICE >= 0 || typeof item.DELIVERY_DISCOUNT_PRICE !== 'undefined')

пишем:

if (item.PRICE > 0 || typeof item.DELIVERY_DISCOUNT_PRICE !== 'undefined')

А также вместо:

else if (deliveryCached && (deliveryCached.PRICE >= 0 || typeof deliveryCached.DELIVERY_DISCOUNT_PRICE !== 'undefined'))

пишем:

else if (deliveryCached && (deliveryCached.PRICE > 0 || typeof deliveryCached.DELIVERY_DISCOUNT_PRICE !== 'undefined'))

И последним нужно скрыть нулевую доставку из итоговых сумм. Для этого в функции editTotalBlock: function() также ставим строгую проверку на ноль. Вместо

if (parseFloat(total.DELIVERY_PRICE) >= 0 && this.result.DELIVERY.length)

пишем:

if (parseFloat(total.DELIVERY_PRICE) > 0 && this.result.DELIVERY.length)

В результате нулевая доставка не будет показана пользователю.

Вариант кастомизации компонента оформления от Александры Плотниковой

Александра написала мне в обратную связь о своем интересном кейсе по доработке одношагового заказа. Пока делюсь ссылкой, позже проработаю и выпишу текстом



Благодарю за внимание! Делитесь вашими замечаниями в комментариях ниже.


P.S. Обращайтесь ко мне за приобретением лицензий и продлений на 1C-Битрикс "Управление сайтом", лицензий на облачную и коробочную версии Битрикс 24 а также за приобретением и внедрением готовых решений на базе 1С-Битрикс от партнеров. За более подробной информацией свяжитесь со мной любым удобным для вас способом


Комментарии

О...мое решение, c моими комментариями :) Но не суть. Обратите внимание на свое решение. Поиск по городу штука не совсем "благодарная". Например мой город Иваново. Не факт, что ваше решение выдаст правильное местоположение. Т.к. г. Иваново у нас в России не один.
  • Ответить

Добавить комментарий

captcha

Возврат к списку