Как добавить в корзину выбранное значение множественного свойства типа строка.
Для начала сам код вывода значений множественного свойства типа "Строка" в карточке товара в виде select:
<div class="select_block"> <?if (!empty($arResult['DISPLAY_PROPERTIES']['top_size']["VALUE"])) { ?> <b><?=$arResult['DISPLAY_PROPERTIES']['top_size']['NAME'];?></b> <select class="top_size" onchange="type_memorial(this);"> <?foreach ($arResult['DISPLAY_PROPERTIES']['top_size']["~VALUE"] as &$arOneProp):?> <option value="<?=$arOneProp?>"> <?=$arOneProp;?> </option> <?endforeach;?> </select> <?}?> </div>
<div class="select_block"> <?if (!empty($arResult['DISPLAY_PROPERTIES']['bottom_size']["VALUE"])) { ?> <b><?=$arResult['DISPLAY_PROPERTIES']['bottom_size']['NAME'];?></b> <select class="bottom_size"> <?foreach ($arResult['DISPLAY_PROPERTIES']['bottom_size']["~VALUE"] as &$arOneProp):?> <option value="<?=$arOneProp?>"> <?=$arOneProp;?> </option> <?endforeach;?> </select> <?}?> </div>
<script> function type_memorial(s) { $num = s.value; $('.bottom_size').val($num).prop('checked'); } </script>
, где top_size и bottom_size - символьные коды необходимых свойств. А скрипт js предназначен для автоматического выбора option-а bottom_size в зависимости от выбранного option-а top_size.
Рассмотрим несколько способов.
При первом способе используется стандартная возможность "Характеристики товара, добавляемые в корзину". Для этого в настройках компонента "Каталог" ставим галочку в поле "Добавлять в корзину свойства товаров и предложений" и выбираем необходимые свойства.
После этого, при нажатии кнопки "Купить" будет открываться модальное окно, от которого нам нужно избавиться (визуально), потому что выбор значения множественного свойства осуществляется в карточке товара и дублировать это действие нет необходимости. Поэтому для автоматической подстановки выбранных значений во всплывающем окне напишем следующий скрипт в template.php (или любом удобном месте) элемента каталога:
$('.bx_cart').click(function () { $top_size = $('.top_size').val(); $("select[name='prop[top_size]'] option[value="+$top_size+"]").attr('selected', true); $("select[name='prop[bottom_size]'] option[value="+$top_size+"]").attr('selected', true); setTimeout(function(){ $(".popup-window-buttons .bx_medium").trigger('click'); }, 1000); })
Теперь поля будут заполнены нужными значениями, а также будет имитирован клик по кнопке "Выбрать". И с помощью стилей скроем модальное окно и overlay:
.popup-window.popup-window-with-titlebar, .popup-window-overlay { display: none !important; }
Второй способ основан на использовании метода CSaleBasket::Update.
В шаблоне карточки товара добавляем следующий код:
<span id="product_id" style="display: none"><? echo $arResult['ID']; ?></span> <script> $(function(){ $(".bx_cart").click(function (e) { var s = $('#product_id').html(); var top_size = $('.top_size option:selected').text(); var bottom_size = $('.bottom_size option:selected').text(); var sendData = { id: s, top: top_size, bottom: bottom_size }; $.ajax({ url: "/ajax/price.php", global: false, type: "POST", data: ({sendData: sendData}) }); return false; }); }); </script>
, где в теге span мы выводим ID текущего товара для последующий передачи его с помощью технологии ajax в файл price.php и дальнейшей обработки.
Содержимое файла price.php:
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); if (CModule::IncludeModule("sale")) { if(CModule::IncludeModule("iblock")) { $ID = $_POST["sendData"]["id"]; $dbBasketItems = CSaleBasket::GetList( array(), array("FUSER_ID" => CSaleBasket::GetBasketUserID(), "PRODUCT_ID" => $ID), false, false, array("ID")); while ($arItems = $dbBasketItems->Fetch()) { $id = $arItems["ID"]; } $arProps = array(); if(isset($_POST["sendData"]["top"])): $arProps[] = array( "NAME" => "Верхний размер", "CODE" => "top_size", "VALUE" => $_POST["sendData"]["top"] ); endif; if(isset($_POST["sendData"]["bottom"])): $arProps[] = array( "NAME" => "Нижний размер", "CODE" => "bottom_size", "VALUE" => $_POST["sendData"]["bottom"] ); endif; $arFields["PROPS"] = $arProps; CSaleBasket::Update($id, $arFields); } } require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php"); ?>
Здесь в первую очередь мы получаем id записи в корзине по id товара (CSaleBasket::GetList - $id = $arItems["ID"]), который мы передали с помощью скрипта. А затем делаем update этой записи, добавляя в нее значения множественных свойств, также переданных с помощью ajax.
Минус способа: при добавлении товара с другим значением множественного свойства не будет добавляться новая запись, а будет затерто предыдущее значение.
Третий способ - добавление товара в корзину "своими силами", используя метод CSaleBasket::Add.
В шаблоне карточки товара добавляем следующий код:
<span id="product_id" style="display: none"><? echo $arResult['ID']; ?></span> <span id="product_price" style="display: none"><? echo $arResult['MIN_PRICE']["VALUE"]; ?></span> <script> $(function(){ $(".bx_cart").click(function (e) { var s = $('#product_id').html(); var value = $('.transparent_input').val(); var top_size = $('.top_size option:selected').text(); var bottom_size = $('.bottom_size option:selected').text(); var price = $('#product_price').html(); var sendData = { id: s, price: price, top: top_size, bottom: bottom_size, value: value }; $.ajax({ url: "/ajax/price.php", global: false, type: "POST", data: ({sendData: sendData}), success: function (data) { window.location.href = "/personal/cart/"; } }); return false; }); }); </script>
, где в тегах span мы выводим ID текущего товара и стоимость единицы товара ($arResult['MIN_PRICE']["VALUE"]) для последующий передачи этих данных с помощью технологии ajax в файл price.php и дальнейшей обработки. Также данному файлу мы передаем значения свойств (как и в способе 2) и количество выбранных товаров ($('.transparent_input').val()).
Содержимое файла price.php:
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); if (CModule::IncludeModule("sale")) { if(CModule::IncludeModule("iblock")) { $res = CIBlockElement::GetByID($_POST["sendData"]["id"]); if ($ar_res = $res->GetNext()) { $name = $ar_res['~NAME']; $det = $ar_res['DETAIL_PAGE_URL']; $arFields = array( "PRODUCT_ID" => $_POST["sendData"]["id"], "PRICE" => $_POST["sendData"]["price"], "QUANTITY" => $_POST["sendData"]["value"], "CAN_BUY" => "Y", "LID" => LANG, "CURRENCY" => "RUB", "NAME" => $name, "CALLBACK_FUNC" => "", "MODULE" => "catalog", "PRODUCT_PROVIDER_CLASS" => "", "NOTES" => "", "ORDER_CALLBACK_FUNC" => "", "DETAIL_PAGE_URL" => $det, ); $arProps = array(); if(isset($_POST["sendData"]["top"])): $arProps[] = array( "NAME" => "Верхний размер", "CODE" => "top_size", "VALUE" => $_POST["sendData"]["top"] ); endif; if(isset($_POST["sendData"]["bottom"])): $arProps[] = array( "NAME" => "Нижний размер", "CODE" => "bottom_size", "VALUE" => $_POST["sendData"]["bottom"] ); endif; $arFields["PROPS"] = $arProps; CSaleBasket::Add($arFields); } } } require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php"); ?>
Здесь мы получаем поля элемента по его id (CIBlockElement::GetByID). А затем добавляем сформированный по нашим параметрам товар в корзину (CSaleBasket::Add).
При этом надо не забыть отменить стандартное действие кнопки добавления в корзину. Иначе в корзину будет добавлено 2 записи.
Чуть более подробно в формате видео: