Добавление в избранное или отложенные, на AJAX из карточки товара

Добавление в избранное или отложенные, на AJAX из карточки товара
Просмотров: 8981 | Комментариев: 22

В этой заметке рассакажу как добавлять товары в "Отложенные", для иммитации функционала "Избранное". Для этого будем использовать 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) курса по разработке интернет-магазина на Битрикс

На этом все. Заметка написана на базе темы на офицальном форуме Битрикс. Дополнена не достающими фактами.

gulnazm
Здравствуйте!
Как при добавление в избранное передать значения выбранных торговых предложений?
Пыталась добавить через параметр "PROPS"  CSaleBasket::Add($arFields);  
вышло таким образом https://c2n.me/3Rn0pZ1
pilot77rus
Присоединяюсь.
Подскажите как добавить в избранное Торговые предложения.
Александр Силуянов
Странно, но у меня через раз работает. Например три-четыре товара добавит, потом перестает реагировать. Потом опять пару товаров добавит и т.д. В чем может быть дело как считаете?
И подскажите как реализовать не в детальной карточке товара, а в списке товаров?
Александр Силуянов
Цитата
Александр Силуянов пишет:
Странно, но у меня через раз работает. Например три-четыре товара добавит, потом перестает реагировать. Потом опять пару товаров добавит и т.д. В чем может быть дело как считаете?
И подскажите как реализовать не в детальной карточке товара, а в списке товаров?
В дополнении к сообщению:
Хром вот такую ошибку выдает при клике Uncaught SyntaxError: missing ) after argument list
Александр Силуянов
Цитата
Александр Силуянов пишет:
Цитата
Александр Силуянов пишет:
Странно, но у меня через раз работает. Например три-четыре товара добавит, потом перестает реагировать. Потом опять пару товаров добавит и т.д. В чем может быть дело как считаете?
И подскажите как реализовать не в детальной карточке товара, а в списке товаров?
В дополнении к сообщению:
Хром вот такую ошибку выдает при клике Uncaught SyntaxError: missing ) after argument list
Проблема решена, потому что я олень))
В названии продукции есть слово L'Oreal и верхний апостроф мешал корректному вызову...
Убрал из кода '<?=$arResult["NAME"]?>', и еще ко что..
Сергей Подварский
Здравствуйте!
Замечательные уроки, всё получается, но есть вопрос, у Вас на сайте есть список отложенных товаров - как его вывести(отдельно от корзины)?  
Сергей Сыроежкин
ошибка здесь, лишняя скобка...
"NAME" => $_POST['name']),
Михаил Базаров
Цитата
Сергей Сыроежкин пишет:
ошибка здесь, лишняя скобка...
"NAME" => $_POST['name']),
Да, спасибо, поправил.
xx24xx22@yandex.ru
День добрый!

Спрашивал, на недавней трансляции, про фичу "Купить в один клик", был послан примерно сюда, а тут не такого  :)
Antik
Интересный момент, битрикс последний, шаблон дефолтный магазина,  при добавлении в избранное товар появляется в корзине, но у него цена пустая, и есть кнопка добавить в заказ http://joxi.ru/brRpkKqCJkEWE2 , но даже при добавлении цена не появляется, я так полагаю потому что не передаётся параметр PRICE?
Михаил Базаров
Цитата
Antik написал:
Интересный момент, битрикс последний, шаблон дефолтный магазина,  при добавлении в избранное товар появляется в корзине, но у него цена пустая, и есть кнопка добавить в заказ  http://joxi.ru/brRpkKqCJkEWE2  , но даже при добавлении цена не появляется, я так полагаю потому что не передаётся параметр PRICE?
Наверное, потому что у Вас каталог с торговыми предложениями. Описанное в заметке, добавляет цену товара, только если он самодостаточный
Просто, передавайте в "избранное" первое попавшееся торговое предложение, а не сам товар.
Артур
Здравствуйте,
подскажите как передать еще торговое предложение в избранное?!
Andrey Sukhanov
Добрый день.
Все работает, но только для авторизованных пользователей.
Также обратил внимание, что другие java скрипты глючат на неавторизованных пользователях, как будто не всё ядро подключено. Пример здесь. В чем может быть дело?
Корзина глючит тоже, форма регистрации не показывает капчу. В общем, какая-то масса проблем с общим корнем, а в документации не нашел ничего.
Михаил Базаров
Цитата
Andrey Sukhanov написал:
Добрый день.
Все работает, но только для авторизованных пользователей.
Также обратил внимание, что другие java скрипты глючат на неавторизованных пользователях, как будто не всё ядро подключено. Пример  здесь . В чем может быть дело?
Корзина глючит тоже ,  форма регистрации  не показывает капчу. В общем, какая-то масса проблем с общим корнем, а в документации не нашел ничего.
Посмотрите, может быть регистрация обязательна в главном модуле
Если нет-то подсказать тяжело, нужно разбираться изнутри
Чуть позже, будет заметка о реализации отложенного- не на базе избранного.  
Константин Ильин
Михаил, спасибо за ваши видео и уроки, помогают разобраться с битриксом.

Хотел бы сказать по поводу данного скрипта, что он плох в безопасности.
Использую ваши заготовки.

Цена передается через аякс, что не есть хорошо!
Вот пример
Через консоль браузера меняю цену:
http://joxi.ru/82QvQ0liwVOe6A

Жму в отложенные, теперь у меня в отложенных лежит товар с ценой 70.00
http://joxi.ru/brRv5Joi7Leger

Перекидываю его в корзину и что я вижу, теперь вместо товара с ценой  20070.00 руб. получаю товар за 70р.
Могу оформить заказ за 70р вместо 20070.00

На вашем сайте так же!
Взял для примера товар
http://bxstore.ru/catalog/item/audio-technica-vm520eb-h-golovka-zvukosnimatelya.php

http://joxi.ru/gmvKvnNcqdX5W2
http://joxi.ru/nAyRxkgTga1Oqr

Я бы сказал это критическая уязвимость...  :!:  

Так же при перекидывание из отложенных в корзину, количество товаров становиться 2, а не 1. Должен же просто меняться флаг на "DELAY" => "N"

Логика наверно должна быть такая, что через аякс передается ID товара, а уже внутри скрипта получаем все данные , в том числе и цену. Мне кажется этот код надо убирать с вашего сайта и написать без уязвимостей.
Михаил Базаров
Цитата
Константин Ильин написал:
Михаил, спасибо за ваши видео и уроки, помогают разобраться с битриксом.

Логика наверно должна быть такая, что через аякс передается ID товара, а уже внутри скрипта получаем все данные , в том числе и цену. Мне кажется этот код надо убирать с вашего сайта и написать без уязвимостей.

Не получилось именно купить такой, "хакнутый" товар. При оформлении заказа, все равно установилась правильная цена.
Но да, минусом это можно назвать.
Да и достаточно, в самом деле, передавать только ID товара в ссылке и скрипте.

Вообще, эта модель, избранное-через отложенные корзины, мне не очень нравится и уже готов компонент нормальных избранных.
Скоро опубликую, в блоге.  Допричесать нужно.
Константин Ильин
Цитата
Михаил Базаров пишет:
Цитата
Не получилось именно купить такой, "хакнутый" товар. При оформлении заказа, все равно установилась правильная цена.
Но да, минусом это можно назвать.
Да и достаточно, в самом деле, передавать только ID товара в ссылке и скрипте.
Понял, далее я не пробовал конечно.

Цитата
Вообще, эта модель, избранное-через отложенные корзины, мне не очень нравится и уже готов компонент нормальных избранных.
Эта модель вообще какой-то бред... я с битриксом не так давно работаю, много что излишне усложнено, но это "плата" за то что многое предусмотрено для всяких контент менеджеров. Ведь за частую много того что не нужно или вообще даже ни разу не будет использоваться.
В этом плане модх конечно выигрывает, так сказать для разработчиков проще.

Цитата
Скоро опубликую, в блоге.  Допричесать нужно.
Здорово! Очень жду! Как завершу проект , надо бы вам на пиво пару рублей закинуть, много уроков ваших помогли. Спасибо еще раз, и жду новых видосов и компонентов :)
dev bosgroup
а как сделать чтобы при повторном нажатии данный товар убирался из "избранного" ??? :(
dev bosgroup
Цитата
dev bosgroup пишет:
а как сделать чтобы при повторном нажатии данный товар убирался из "избранного" ???
к слову пробовал - CSaleBasket:: Delete(ID) но это не работает
Алексей Шрейбер
А как сделать чтобы товары из избранного не удалялись при оформлении заказа в корзине? Пользователь оформляет заказ и все его сохраненные товары исчезают
Страницы: 1 2 След.