В этой заметке рассакажу как добавлять товары в "Отложенные", для иммитации функционала "Избранное". Для этого будем использовать API 1С-Битрикс. Добавление будет происходить на AJAX- без перезагрузки страницы
Выводим количество отложенных товаров
В штатной корзине sale.basket есть отложить товар. Наша задача вывести количество отложенных товаров в шаблоне сайта, например в шапке и назвать "Избранное"- вот в таком виде:

Для этого, в нужном месте шаблона выводим следующий код:
<?
use Bitrix\Main\Loader;
Loader::includeModule("sale");
$delaydBasketItems = CSaleBasket::GetList(
array(),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL",
"DELAY" => "Y"
),
array()
);
echo $delaydBasketItems;
?>
В переменную $delaydBasketItems - мы передали и вывели количество отложенных товаров, отфильтровав их параметром "DELAY" => "Y". Если не использовать данный параметр- нам выведется общее количество товаров в корзине, вместе с готовыми к покупке.
Создаем обработчик для добавления товара из карточки.
Далее создаем файл wishlist.php и ложим его в директорию /local/ajax/. Внутри этого файла размещаем следующий код (подсказки по коду в комментриях)
<?
//Подключаем ядро Битрикс и главный модуль
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
use Bitrix\Main\Loader;
//Подключаем модуль sale
Loader::includeModule("sale");
//Получаем корзину текущего пользователя
$fUserID = CSaleBasket::GetBasketUserID(True);
$fUserID = IntVal($fUserID);
//Создаем переменные для обработчика
$arFields = array(
"PRODUCT_ID" => $_POST['p_id'],
"PRODUCT_PRICE_ID" => $_POST['pp_id'],
"PRICE" => $_POST['p'],
"CURRENCY" => "RUB",
"WEIGHT" => 0,
"QUANTITY" => 1,
"LID" => 's1',
"DELAY" => "Y",
"CAN_BUY" => "Y",
"NAME" => $_POST['name'],
"MODULE" => "sale",
"NOTES" => "",
"DETAIL_PAGE_URL" => $_POST['dpu'],
"FUSER_ID" => $fUserID
);
//Получаем количество отложеных товаров
if (CSaleBasket::Add($arFields)) {
$arBasketItems = array();
$dbBasketItems = CSaleBasket::GetList(
array(
"NAME" => "ASC",
"ID" => "ASC"
),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL",
"DELAY" => "Y",
),
false,
false,
array("PRODUCT_ID")
);
while ($arItems = $dbBasketItems->Fetch()){
$arBasketItems[] = $arItems["PRODUCT_ID"];
}
//Загоняем отложенне в переменную
$inwished = count($arBasketItems);
}
//Выводи количество отложенных товаров
echo $inwished;
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");
?>
Этот обработчик будет получать событие о добавлении товара в отложенные. В детальной карточке товара размещаем скрипт который будет обращаться, к созданному выше обработчику, точнее передавать в него параметры товара:
function add2wish(p_id, pp_id, p, name, dpu, th){
$.ajax({
type: "POST",
url: "/local/ajax/wishlist.php",
data: "p_id=" + p_id + "&pp_id=" + pp_id + "&p=" + p + "&name=" + name + "&dpu=" + dpu,
success: function(html){
$(th).addClass('in_wishlist');
$('#wishcount').html(html);
}
});
};
И здесь же, в карточке товара, размещаем ссылку которая будет инициализировать скрипт и передавать параметры о товаре и цене.
<a href="javascript:void(0)" class="wishbtn <? if (in_array($arResult["ID"],$arBasketItems )) echo 'in_wishlist '; ?>"
onclick="add2wish(
'<?=$arResult["ID"]?>',
'<?=$arResult["CATALOG_PRICE_ID_1"]?>',
'<?=$arResult["CATALOG_PRICE_1"]?>',
'<?=$arResult["NAME"]?>',
'<?=$arResult["DETAIL_PAGE_URL"]?>',
this)">
Добавить в избранное / отложенные
</a>
При клике, на эту ссылку, товар будет добавлен в отложенные и самой ссылке присвотся класс in_wishlist- что бы можно было ее стилизовать под дизайн
Обновление счетчика отложенных
И еще одна мелочь. Это обновление счетчика Избранных в шапке сайта. Что бы он обновлялся на лету- просто обворачиваем вывод счетчика (созданный выше) в div c id wishcount. Вот так
<div id="wishcount">
<?
use Bitrix\Main\Loader;
Loader::includeModule("sale");
$delaydBasketItems = CSaleBasket::GetList(
array(),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"ORDER_ID" => "NULL",
"DELAY" => "Y"
),
array()
);
echo $delaydBasketItems;
?>
</div>
Что бы не сбрасывался стиль кнопки, в карточке товара- если данный товар есть в отложенных
//Проверяем, есть ли данный товар в отложенных
$curProductId = $arResult['ID'];
$dbBasketItems = CSaleBasket::GetList(
array(
"NAME" => "ASC",
"ID" => "ASC"
),
array(
"FUSER_ID" => CSaleBasket::GetBasketUserID(),
"LID" => SITE_ID,
"PRODUCT_ID" => $curProductId,
"ORDER_ID" => "NULL",
"DELAY" => "Y"
),
false,
false,
array("PRODUCT_ID")
);
while ($arItems = $dbBasketItems->Fetch())
{
$itInDelay = $arItems['PRODUCT_ID'];
}
//Добавляем к кнопке class
if ( (in_array($arResult["ID"], $delaydBasketItems)) || (isset($itInDelay)) ) { echo 'in_wishlist'; }
Выше, мы просто проверили наличие данного товара (по его ID), есть ли он в отложенных. Если есть, загнали в переменную $itInDelay его ID. В самой кнопке-ссылке, проверили на существование переменной $itInDelay (точнее, что она не пустая)
Более наглядное применение в видео-инструкции.
Данное видео является одной из серий (19) курса по разработке интернет-магазина на Битрикс
На этом все. Заметка написана на базе темы на офицальном форуме Битрикс. Дополнена не достающими фактами.
Поддержать выпуски видео уроков, поблагодарить за полезную инструкцию или заметку можно через:
Юманей
Цитата |
---|
Александр написал: А как сделать чтобы при наведении на значек корзины выводилось ее содержимое( краткое описание и маленькое фото ) ,BX.addCustomEvent ? не в ту сторону копаю? |
В штатном шаблоне корзины sale.basket.basket.line это уже есть. Верстка в файле ajax_template.php

Цитата |
---|
Алексей написал: Добрый вечер, с детальной карточки товара товар добавляется в избранное, а как добавить товар в избранное с catalog.item или catalog.section? |
Нужно правильно передать ID товара. В catalog.item это $item['ID'] в catalog.section, вроде бы $arElement['ID']

По сути, нужно сделать обратное действие: не добавить товар в отложенные корзины а удалить его оттуда.
Для этого, можно проверить наличие этого товара в отложенных и если он там есть использовать метод
CSaleBasket::Delete
Код |
---|
if (CSaleBasket::Delete(ПЕРЕДАЕМ ID ЗАПИСИ ПО ID ТОВАРА)) { обработчик который обновит счетчик } |
Если будет время, дополню эту заметку. Но ориентир, в какую сторону копать дал)
