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

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

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

Просмотров: 22792 | Комментариев: 23
Внимание! все сообщения проходят премодерацию. Ваше сообщение появится после проверки
 
Текст сообщения*
Перетащите файлы
Ничего не найдено
Защита от автоматических сообщений
Загрузить файл
Нажимая кнопку "Отправить", Вы принимаете условия
Политики конфиденциальности и обработки персональных данных
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) но это не работает
Имя Цитировать
Алексей Шрейбер
А как сделать чтобы товары из избранного не удалялись при оформлении заказа в корзине? Пользователь оформляет заказ и все его сохраненные товары исчезают
Имя Цитировать
a13z2005@yandex.ru
Михаил Базаров,
подскажите пожалуйста, как на аяксе реализовать вывод избранных товаров?
используя функционал из данного урока.

при клике на кнопку добавить в избранное у вас меняется сразу же счетчик.
к примеру к нему добавлю всплывающее окно - и в нем выведу "отложенные" - тогда они там появляются только после перезагрузки страницы, а хотелось бы чтоб сразу всплывали.
Имя Цитировать
a13z2005@yandex.ru
Михаил Базаров,  Подскажите пожалуйста  как сделать чтобы не сбрасывался стиль кнопки, в списке товаров- если данный товар есть в отложенных?!
Имя Цитировать
Андрей Сенин
Реализация вполне не плохая, но на самом деле я бы делал по-другому:
Во первых, скрипт передает цену, указанную в параметре "&p=" напрямую, а это говорит о том, что я могу в любой момент подменить цену в html на любую другую и она попадет в отложенные в корзину, где я смогу "вернуть" товар в корзину и купить по этой цене.
Во вторых, в идеале убрать jQuery и забиндить обработчик на Bitrix JS и реализовать с помощью ajax битрикса в файле script.js шаблона.

Спасибо за статью;)
Имя Цитировать
Михаил Базаров
Цитата
Андрей Сенин написал:
Реализация вполне не плохая, но на самом деле я бы делал по-другому:
Во первых, скрипт передает цену, указанную в параметре "&p=" напрямую, а это говорит о том, что я могу в любой момент подменить цену в html на любую другую и она попадет в отложенные в корзину, где я смогу "вернуть" товар в корзину и купить по этой цене.
Во вторых, в идеале убрать jQuery и забиндить обработчик на Bitrix JS и реализовать с помощью ajax битрикса в файле script.js шаблона.

Спасибо за статью;)
В целом да. Только с подменой цены не согласен ) - оформление заказа не даст оформить с поддельной ценой.
Понятное дело, не сам компонент оформления заказа, а "подкапотная" реализация.

У меня уже готов свой компонент избранного, пишет все отдельную табличку БД - на нескольких проектах работает успешно. Скоро (не знаю когда :) ) заверну его в установщик и поделюсь.
Имя Цитировать
Алексей
Добрый день!
Скажите пожалуйста а как добавить кнопку удалить из избранного для одного товара из списка.
Удалить все -работает
Но хочется по одному удалять
Имя Цитировать
Вячеслав
Цитата
написал:
Цитата
Андрей Сенин написал:
Реализация вполне не плохая, но на самом деле я бы делал по-другому:
Во первых, скрипт передает цену, указанную в параметре "&p=" напрямую, а это говорит о том, что я могу в любой момент подменить цену в html на любую другую и она попадет в отложенные в корзину, где я смогу "вернуть" товар в корзину и купить по этой цене.
Во вторых, в идеале убрать jQuery и забиндить обработчик на Bitrix JS и реализовать с помощью ajax битрикса в файле script.js шаблона.

Спасибо за статью;)
В целом да. Только с подменой цены не согласен ) - оформление заказа не даст оформить с поддельной ценой.
Понятное дело, не сам компонент оформления заказа, а "подкапотная" реализация.

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

У меня уже готов свой компонент избранного, пишет все отдельную табличку БД - на нескольких проектах работает успешно. Скоро (не знаю когда  ) заверну его в установщик и поделюсь.
Михаил, еще не выкладывали компонент? Может я пропустил) Как вариант на маркетплейс можно закинуть за пару рубчиков

Пока нет, но скоро :)  
Имя Цитировать

Цены на разработку сайта или приложения

Что бы узнать точные стоимость и срок разработки:
достаточно, как можно подробнее, заполнить опросник и выслать на электронную почту info@bazarow.ru.
После ознакомления, смогу задать уточняющие вопросы и оценить.

В стоимость разработки уже включены и не требуют доплат:
  • Лицензия на необходимую редакцию 1С-Битрикс: Управление сайтом и лицензии на дополнительные модули, если требуются для конкретного проекта.
  • Применение технологии композитный сайт: Оптимизация скорости работы проекта под нагрузками.
  • Один год, бесплатной, технической поддержки от 1С-Битрикс
Интернет-магазин от 250 000 рублей
Полно-комплексная разработка интернет-магазина любой сложности. Интеграция с 1С, службами доставки и оплаты. Внутренняя СЕО оптимизация перед запуском.
Сайт компании от 200 000 рублей
Сайт с каталогом товаров или услуг, без функционала магазина. Включает формы обратной связи внутри карточек каталога. Любое количество статичных и динамичных разделов.
Инфоресурс от 200 000 рублей
Портал или доска объявлений с большим количеством разделов. Возможность включения форумов, блогов, регистрации пользователей, внутри сайтовая социальная сеть.
Сайт на готовом решении от 40 000 рублей
Подбор решения из более 200-от готовых сайтов, в соответствии с тематикой бизнеса. Запуск сайта на сервере или хостинге, со всеми настройками. Не большие доработки под задачу.
Мобильное приложение от 200 000 рублей

Кроме сайтов, занимаюсь разработкой мобильных приложений на технологии Apache Cordova. Это полноценные приложения, которые публикуются и распостранияются через официальные магазины GooglePlay и AppStore

  • Полная интеграция с базой данных, основного сайта.
  • Вывод каталогов продукции и услуг, прямо в приложении.
  • Персональные разделы пользователей с историей заказов.
  • Прямой доступ к устройству: GPS, камера, звонки и медиабиблиотека

attention