Как добавить в корзину выбранное значение множественного свойства типа строка.
Для начала сам код вывода значений множественного свойства типа "Строка" в карточке товара в виде 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 записи.
Чуть более подробно в формате видео: