FENOM'енальный курс. Часть 8. Выводим цвета и размеры товара, добавляем их в корзину.

Шаблон MAGAZINE вы можете скачать по ссылке.

Данный урок будет задевать не только конкретные опции, а вообще все опции в целом. Логика их добавления примерно одинакова. Для цвета мы будем использовать платный компонент msOptionsColor из modstore.pro.

Начнем непосредственно с выбора цвета. Для активации вкладки “Цвета” у товаров, нам необходимо перейти в системные настройки и задать значение для ключа msoptionscolor_working_templates – идентификатор шаблона товара. Должно получиться примерно как на скриншоте:

FENOM'енальный курс. Часть 8. Выводим цвета и размеры товара, добавляем их в корзину.

Теперь у нас должна быть активна вкладка “Цвета” у товаров с шаблоном, имеющим id 11 ( в моем случае). Предлагаю вам выбрать товар, жертву экспериментов, на котором мы с вами будем проводить опыты. Сразу напомню, что мы еще будем реализовывать размеры товаров, поэтому желательно выбрать такой товар, где есть и то и другое. Например, кроссовки:

FENOM'енальный курс. Часть 8. Выводим цвета и размеры товара, добавляем их в корзину.

Заметили появившуюся вкладку цвета? Сейчас мы с вами будем с ней работать. Только перед тем как приступить заполните цвета и размеры так же как у меня на скриншоте выше. Заполнили? Отлично! Открываем вкладку цвета и видим, какие именно опции нам необходимо отредактировать:

FENOM'енальный курс. Часть 8. Выводим цвета и размеры товара, добавляем их в корзину.

Кликаем “редактировать” и заполняем соотношение цвета текстового и цвета визуального:

FENOM'енальный курс. Часть 8. Выводим цвета и размеры товара, добавляем их в корзину.

FENOM'енальный курс. Часть 8. Выводим цвета и размеры товара, добавляем их в корзину.

Отлично! Все получилось и цвета можно выводить в карточке товара. За это у нас отвечает сниппет msOptionsColor, который мы вызываем в шаблоне на месте наших цветов товара:

{$_modx->runSnippet('msOptionsColor', [
	'options' => 'color',
	'tpl' => '@FILE chunks/color_product.tpl'
])}
	

И, конечно, нужно создать чанк color_product.tpl:

{foreach $colors as $name => $color}
<div class="product-color">
  <div class="sub-title">Выберите цвет:</div>
  <div class="colors">
	{foreach $color as $row index=$index}
	<div class="item form-check form-check-inline">
	  <input class="form-check-input" type="radio" name="options[{$name}]" value="{$row.value}" {$index ? '' : 'checked'}>
	  {if $row.pattern?}
	  <div>
		<img alt="" title="{$row.value}" class="img-rounded" style="background-image:url({$row.pattern});width:25px;height:25px;">
	  </div>
	  {else}
	  <div>
		<img alt="" title="{$row.value}" class="img-rounded" style="background-color:#{$row.color};width:25px;height:25px;">
	  </div>
	  {/if}
	</div>
	{/foreach}
  </div>
</div>
{/foreach}
	

Отлично! Цвета мы вывели. Приступим к размерам?

Для вывода размеров я использую сниппет getsizes, который производит сортировку значений размеров. Тут тоже важно заметить, что постоянно возникает проблема с сортировкой опций. Сниппет getsizes:

<?php
$id = $modx->resource->id;

$pdoTools = $modx->getService('pdoTools');
$product = $modx->getObject("msProduct", $id);
$sizes = $product->get("size");
if(count($sizes)){
	asort($sizes);
	$row['options'][] = $sizes;
	$res = $pdoTools->getChunk('@FILE chunks/size_product.tpl', $row);
	$modx->setPlaceholder("sizes", $res);
}
	

И, конечно, чанк size_product.tpl (обратите внимание как он вызван в API):

{foreach $options as $name => $values}
  {foreach $values as $value => $val}
  
	<span class="pick-size-class {if $value == 0}active{/if}">
	  <input class="hidden" type="radio" name="options[size]" value="{$val}" id="size[{$val}]" required {$value ? '' : 'checked'}/>{$val}
	</span>
  
  {/foreach}
{/foreach}
	

Как вы успели заметить данный сниппет сортирует опции и выставляет плейсхолдер sizes, который мы можем обработать в шаблоне:

{'@FILE snippets/getsizes.php' | snippet : []}
{if $_modx->getPlaceholder('sizes')?}
	<div class="product-size">
		<div class="sub-title">Выберите размер (<a href="#" data-toggle="modal" data-target="#sizetable">уточнить</a>):</div>
		{$_modx->getPlaceholder('sizes')}
	</div>
{/if}
	

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

А теперь вернемся с вами к нашей задаче. В начале статьи я написал, что мы затронем не только конкретные опции, а вообще опции в целом, как их выводить и принцип их работы. Пожалуй, до следующего урока я оставлю данный вопрос открытым, а вам предлагаю посмотреть на сходства размеров и цветов, так же увидеть в чем их различия. Дам маленькую подсказку: HTML-форма и ее элементы.

FENOM'енальный курс. Часть 8. Выводим цвета и размеры товара, добавляем их в корзину.

0 Число голосов: 6
4
5
1
6

Комментарии ()

  1. Дмитрий 10 марта 2019, 02:44 # 0
    По ссылке приведенной Вами, для тестирования, данный компонент отсутствует, к сожалению…
    1. Алексей 29 апреля 2019, 16:30(Комментарий был изменён) # 0
      \
      1. Петропавловский Артем 29 апреля 2019, 17:00 # 0
        Нужно модернизировать скрипт вот так:
        <?php
        if(!$id){
            $id = $modx->resource->id;
        }
        
        $pdoTools = $modx->getService("pdoTools");
        $product = $modx->getObject("msProduct", $id);
        if ($product){
        	$sizes = $product->get("size");
        	if(count($sizes)){
        		asort($sizes);
        		$row['options'][] = $sizes;
        		$res = $pdoTools->getChunk("@FILE chunks/tpl_sizes.tpl", $row);
        		//$modx->setPlacegolder("sizes", $res);
        		return $res;
        	}
        }
        
        И тогда его можно будет вызвать вот так:
        {$_modx->runSnippet("@FILE snippets/get_sizes.php", ['id' => $id])}
        То есть в параметр «id» передавать идентификатор интересующего нас ресурса.
      2. Александр 10 марта 2021, 16:07 # 0
        Здравствуйте, столкнулся с проблемой. Мне нужно вывести в корзине выбранный покупателем размер в карточке товара.Т.е. суть такая, покупатель на карточке товара выбирает размер, нажимает на кнопку «в корзину» и при открытии корзины он видит выбранный им размер в таблице с товаром.Как это можно осуществить, бьюсь вторые сутки, очень благодарен буду за ответ!
        1. Петропавловский Артем 10 марта 2021, 17:24(Комментарий был изменён) # 0
          Передайте в сниппет корзины msCart пустой параметр tpl. Тогда вы сможете увидеть все, что попадает в корзину (для удобства обрамите вывод тегом pre, тогда код станет читабельнее). Для начала разберитесь попадает размер в корзину или нет, если попадает, он будет в products.options. Могу в рамках платной консультации рассказать как решать подобные вопросы.
          1. Александр 12 марта 2021, 09:46 # 0
            Сделал так как вы сказали, в корзину размер передается, но массивом, а как сделать так что бы отображался только тот размер, который выбрал покупатель в карточке товара? Сколько будет стоить ваша платная консультация по этому вопросу?
            1. Петропавловский Артем 12 марта 2021, 09:52(Комментарий был изменён) # 0
              1200 руб./час. Консультацию я хотел провести не по этому вопросу, а рассказать о том, как это работает в MODX. Возможно, где-то показать на примерах. Чтобы вам было понятнее. А, чтобы вывести конкретный размер в корзине и чанке письма, воспользуйтесь конструкцией:
              {foreach $products as $product}
              <tr id="{$product.key}">
              	<td class="cart-image">
              		{if $product.image}
              		  <img src="{$product.image}" alt="{$product.pagetitle | htmlent}" title="{$product.pagetitle | htmlent}">
              		{else}
              		  <img src="{$_modx->getPlaceholder('+noimage')}" alt="{$product.pagetitle | htmlent}" title="{$product.pagetitle | htmlent}"/>
              		{/if}
              	</td>
              	<td class="">
              		<a href="{$product.id | url}">{$product.pagetitle | htmlent}</a><br>
              		{if $product.options?}
              			{foreach $product.options as $key => $option}
              				{if $key in ['modification','modifications','msal']}{continue}{/if}
              		
              				{set $caption = $product[$key ~ '.caption']}
              				{set $caption = $caption ? $caption : ('ms2_product_' ~ $key) | lexicon}
              				
              				{if $option is array} 
              				{$caption} - {$option | join : '; '} <br>
              				{else}
              				{$caption} - {$option} <br>
              				{/if}
              				
              			{/foreach}
              		{/if}
              	</td>
              	<td class="count">
              		<form method="post" class="ms2_form form-inline" role="form">
              			<input type="hidden" name="key" value="{$product.key}">
              			<div class="form-group">
              				<input type="number" name="count" value="{$product.count}" max-legth="4" class="input-sm form-control"> шт. <button class="btn btn--cart" type="submit" name="ms2_action" value="cart/change"><i class="fa fa-refresh" aria-hidden="true"></i></button>
              			</div>
              		</form>
              	</td>
              	<td class="price"><span>{$product.price}</span> руб.</td>
              	<td class="nds_price">
              		<span>{$product.cost}</span> руб.
              	</td>
              	<td class="">
              		<form method="post" class="ms2_form">
              			<input type="hidden" name="key" value="{$product.key}">
              			<button class="btn btn--cart" type="submit" name="ms2_action" value="cart/remove" title="Удалить"><i class="fa fa-times" aria-hidden="true"></i></button>
              		</form>
              	</td>
              </tr>
              {/foreach}
              Я намеренно вывел кусок с выводом товаров полностью. Обратите внимание на конструкции с $product.options
              1. Александр 12 марта 2021, 16:53(Комментарий был изменён) # 0
                Спасибо вам огромное за ответ, но почему то у меня ничего не отображается. Кусок кода {if $product.options?}… {/if} должен отображать как я понимаю все опции товара кроме ['modification','modifications','msal'], но у меня ничего не выводится, как будто опций вообще нет, не пойму что не так. В скриншотах приложил свой код, если сможете подскажите пожалуйста что у меня не так. ibb.co/4WrsQms и ibb.co/sCdbCG0 Как видите код размер: {$product.size[0]} размер: 52-53 выводит а вот ниже ничего нет :-( И что интересно, если из кода убрать 'modification', то в корзине отобразится: ms2_product_modification — 0 Артем, помогите пожалуйста разобраться…
                1. Петропавловский Артем 12 марта 2021, 17:02 # 0
                  Мне кажется, что у вас некорректно добавляется размер в корзину. Атрибут name у input опции должен быть следующий: options[size], где size — ключ опции.
                  1. Александр 12 марта 2021, 17:42(Комментарий был изменён) # 0
                    Точно! Артем, все заработало, во время правок msOptionTpl я убрал тег «name».Спасибо вам огромное, вы очень мне помогли! Вы человечище! :-)
                    1. Петропавловский Артем 12 марта 2021, 17:59 # 0
                      Всегда пожалуйста)
        2. Димка 23 марта 2021, 17:02(Комментарий был изменён) # 0
          Здраствуйте. А не скажете как возможно реализовать такую штуку с размерами обуви?
          1. Петропавловский Артем 23 марта 2021, 17:35 # 0
            Вам нужно создать таблицу соответствия размеров (например, с помощью MIGX) и обрабатывать размер по своему алгоритму (с помощью JS).
          2. Петя 03 апреля 2021, 01:33(Комментарий был изменён) # 0
            <img alt="" title="{$row.value}" class="img-rounded" style="background-image:url({$row.pattern});width:25px;height:25px;">
            — почему img, а не div? img без srс и в добавок с пустым alt — дважды не валидно)
            1. Петропавловский Артем 03 апреля 2021, 08:56 # 0
              Вы в праве менять разметку, как вы хотите. Здесь показаны лишь принципы работы с компонентом.
            2. Олег 02 февраля 2022, 12:22 # 0
              А этот код рабочий? Я сделал все по шагам, но не для поля size, например, а сделал сам поле с типом minishop2-combo-options. Соответственно не вешается класс active и нет реакции инпута на checked. Можно ли как то попроще сделать вывод — для идиотов, типа на эту кнопку значение $array[0], на другую $array[1]?

              Наши клиенты

              Многие компании уже доверяют нам. Будьте в их числе!

              Хотите реализовать проект?

              Контакты

              Напишите нам - мы расскажем вам много интересного!


              Пермь, ул. Крупской 34, офис 510