28 апреля 2018

Урок 10. AJAX корзина Битрикс своими руками

Приветствую дорогие читатели. Очень долго меня не было - было много работы, но я возвращаюсь и продолжаю заниматься уроками Битрикс. Меня уже несколько раз просили написать статью, как сделать AJAX корзину и в этом уроки мы её сделаем своими руками.
Реализацию сделаем самым простым способом через нативный JavaScript. А в следющем уроке я сделаю тоже самое, но уже через JQuery.
Разобъем наш урок на три части:
  1. Реализуем вызов функции работающей через AJAX запрос.
  2. Реализуем хранение нашей AJAX корзины в сессиях php.
  3. Разместим блок корзины в шаблоне.

Реализуем вызов функции работающей через AJAX запрос

Работать мы будем так же в шаблоне детальной страницы товаров local/templates/startshop/components/bitrix/news/catalog/bitrix/news.detail/.default/template.php. В верстке у нас есть кнопка Купить и поле ввода количества. Единственное нам нужно передать в корзину ID товара, а для этого его нужно где-то хранить. Для хранения ID товара мы добавим ещё один скрытый INPUT и поместим в него ID товара.
Код:
<input type="text" id="middle-label" placeholder="Введите количество">
<input type="hidden" id="element_id" value="<?=$arResult['ID']?>"><!-- Поле для хранения ID товара -->

<a class="button large expanded" onclick="Buy()">Купить</a>
И далее с  этими тремя элементами мы и будем работать.
В поле ввода <input> нас интересует id элемента. Именно по id мы будем искать элемент в дереве элементов и получать значение введенное в поле. А для кнопки, которая у нас определена тегом <A> мы добавим событие на нажатие кнопки и укажем, что необходимо выполнить функцию "Buy()".
Теперь нам нужно ниже верстки определить тег <script> и на языке JavaScript описать работу функции Buy.
Код:
<script>
function Buy() {
const kol = document.getElementById('middle-label').value;/Получаем количество из поле ввода
const id = document.getElementById('element_id').value;/Получаем ID товара
var formData = new FormData();/Создадим объект для передачи данных
formData.append('id', id);/Добавим переменную с ID товара
formData.append('kol', kol);/Добавим переменную с количеством товаров
/ajax
var HttpRequest = new XMLHttpRequest();/Создадим объект для отправки AJAX запроса
HttpRequest.onload = function(e) {
if (this.status == 200) {/Проверка что результат отчета успешный (может быть 404 или другие)
alert('Товар добавлен в корзину');/Сообщение
document.getElementById('chart-value').innerText = this.response;/Записываем цифру в элемент корзины в верстке
}
};/Функция в которую возвращается ответ от сеовера
HttpRequest.open("POST", '/startshop.ru/personal/cart/', true);/Настройка запроса для отправки (второй параметр путь к PHP скрипту)
HttpRequest.send(formData);/Отправка запроса на сервер
}
</script>

В этой функции я не стал пользоваться JQuery, а выполнил AJAX запрос через стандартный функционал JavaScript. В комментариях я расписал, что делает каждая строчка кода. Более подробную информацию о работе XMLHttpRequest можно найти в интернете.
Но все таки немного поясню, что делает код выше: он получает в переменные id и  kol значения id товара и введенное количество, далее добавляет их в специальный объект formData потому что просто строку или число отправить по AJAX не получится. Затем метод send() отправляет POST запрос к файлу /startshop.ru/personal/cart/index.php (index.php можно не указывать, его подставит движок Битрикса). И ещё один момент: у меня указан путь с /startshop.ru/, т.к. включена многосайтовость, если у вас один сайт то указывать домен не нужно, достаточно указать только относительный путь /personal/cart/.

Использую JavaScript и технологию AJAX мы послали некий набор данных на вход php файла. Он их примет, обработает и отправит что-нибудь в ответ. В этом и суть AJAX взаимодействия.


Далее рассмотрим PHP код серверного обработчика AJAX запроса.

Реализуем хранение нашей AJAX корзины в сессиях php

Создадим в корне сайта папку personal и в ней папку cart. Затем файл index.php в котором и разместим PHP код обработки запроса.
Код:
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');/Обязательная строка инициирующая движок Битрикса, но не подключающая шаблон
$id = $_POST['id'];/Получаем из глабального массива $_POST id товара
$kol = $_POST['kol'];/Получаем количество
if (!empty($_SESSION['BX_CART'])) {/Проверяем существует ли наша корзина в массиве $_SESSION
$arChart= $_SESSION['BX_CART'];/Если да то получаем текущиие данные о корзине
} else {
$arChart = array();/Если нет присваиваем пустой массив
}
$arChart[$id] = $arChart[$id]+$kol;/Значение элемента массива с id товара увеличиваем на введенное количество
$_SESSION['BX_CART'] = $arChart;/Сохраняем в сесии массив с корзиной
echo count($_SESSION['BX_CART']);/Возвращаем количество отдельных позиций в корзине
/print_r($_SESSION['BX_CART']);/Вернем ответ о содержании корзины

Я весь код снабдил подробными комментариями, должно быть понятно. Если есть вопросы задавайте в комментариях.

Если для отладки раскомментировать последнюю строку в ответ на нажатие кнопки Купить мы получим сообщение следующего вида:

Содержимое AJAX корзины на Битрикс

Значит у нас все работает правильно.

А далее нам нужно разместить нашу AJAX корзину на экране. Т.е. добавить блок отображения содержимого корзины в верстку нашего шаблона.

Разместим блок корзины в шаблоне

Блок корзины мы разместим в панели меню шаблона. Подробно верстку меню я рассматривал в этом уроке (вывод меню Битрикс). Файл компонента меню у нас находится по пути local/templates/startshop/components/bitrix/menu/menu-fundation/template.php.
Для блока корзины нам достаточно добавить только одну строку кода в список <LI>.
Код:
<ul class="menu">
<li> <div class="chart"><p id="chart-value">0</p></div></li><!-- Блок корзины -->
<li><input type="search" placeholder="Search"></li>
<li><button type="button" class="button">Search</button></li>
</ul>

Т.е. мы выводим блок с классом chart и параграф текста с id=cart-value именно по этому id мы будем находить элемент и записывать в него количество товаров добавленных в корзину. В JavaScript коде у нас есть строчка, которая и будет передавать данные от сервера в блок корзины.
Код:
document.getElementById('chart-value').innerText = this.response;/Записываем цифру в элемент корзины в верстке

Добавим немного верстки. Напомню верстку мы располагаем в файле local/templates/startshop/template_styles.css.
Код:
.chart {
width: 48px;
height: 48px;
background-image: url("/upload/img/chart.jpg");
background-size: 48px 48px;
background-repeat: no-repeat;
margin-right: 10px;
}
.chart p {
color: red;
text-align: center;
font-weight: bold;
font-size: 30px;
}

После всех манипуляций наша Корзина будет выглядеть следующим образом:

Корзина в шапке

Вот собственно и все. Осталось только выводить данные в корзину при переходе по товарам.
А это мы решим еще проще, просто заменив в строке вывода корзины
Код:
<li> <div class="chart"><p id="chart-value">0</p></div></li>
ноль на PHP код, который рассчитает количество товаров из сессии. Вот так:
Код:
<li> <div class="chart"><p id="chart-value"><?=count($_SESSION['BX_CART']);?></p></div></li>

Вот теперь наша AJAX корзина в интернет-магазине на Битрикс готова.
Архив магазина шаблона StartShop на момент урока можно скачать отсюда.

От автора:
Ну вот мы рассмотрели самую интересную на данный момент тему AJAX запросы. Сейчас практически все взаимодействия строятся через AJAX. Красиво, но как вы видите достаточно прилично усложняет код. В следующем уроке я рассмотрю работу с корзиной в списке товаров и там я размещу JacaScript в отдельном файле, а взаимодействие сделаю с помощью библиотеки JQuery. Посмотрите разницу: Урок 12. AJAX запрос средствами JQuery в Bitrix. До новых встреч.


Комментарии

Подписаться на комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
19
25.11.2019 | Вадим

Добрый день. А подскажи пожалуйста, как вывести потом массив именно такого вида? Array ( ["ID"] => 3580, ["KOL"] => 11 )

Комментировать
Подписаться на комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
19
Закрыть
25.11.2019 | Администратор

Функция print_r() в таком виде выводит.

Комментировать
Подписаться на комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
19
Закрыть
25.11.2019 | Вадим

Выводит не в том виде, в котором мне нужно! Он выводит: Array([271] => 1) а мне нужно: Array(["ID"] => 271, ["KOL] => 1)

Комментировать
Подписаться на комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
19
Закрыть
25.11.2019 | Администратор

Для этого придется вручную сформировать массив записав данные нужным образом в него. Автоматической функции для этого нет.

Комментировать
Подписаться на комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
19
Закрыть
23.04.2019 | Администратор

Видимо я хотел завязаться на сесии битрикса. Но так не сделал. В итоге эта строчка лишняя.

Комментировать
Подписаться на комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
19
Закрыть
23.04.2019 | Андрей

Добрый день, спасибо за статью. По мере прочтения возник вопрос, для чего в коде обработки запроса, используется $bx_sessid = bitrix_sessid()?

Комментировать
Подписаться на комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
19
Закрыть


Возврат к списку