Робимо кошик покупок за допомогою Codeigniter та JQuery
У шостій частині статті, як і обіцяв, зробимо наш кошик аяксовим, а також стилізуємо його за допомогою CSS.
Стаття обіцяє бути довгою, тому запасіться терпінням, нам треба багато вивчити та зробити.
Т.к. вивчення CSS не входить до планів цих уроків, то я просто наведу вже готовий код без пояснень. На перших уроках ми створювали файлassets/css/styles.css, який був порожнім. У цьому файлі і зберігатиметься весь CSS код сайту:
assets/css/styles.css
AJAX кошик
Ось ми й дісталися найцікавішого - написання клієнтського js коду функціонала ajax кошика. В основному шаблоні вже з перших уроків підключено бібліотеку jQuery та скриптcart.js, в якому ми писатимемо весь js код.
application/views/template.php
Відкривайте файлcart.js і напишіть таке:
assets/js/cart.js
Це анонімна функція, яка відразу викликається, щоб виключити конфлікти з іншими скриптами js (хоч у нас їх і немає, але потрібно звикати до хорошого).
Нам потрібно створити форми (додавання в кошик, видалення товару з кошика та інші) аяксовими. Тому при натисканні на кнопку, ми будемо посилати AJAX запит на сервер, і в залежності від результату, який повернув сервер, виконувати якісь дії (наприклад виводити повідомлення користувачу).
Давайте додамо цю можливість кнопкам "купити":
assets/js/cart.js
Отже, розберемо, що тут вийшло. Для початку за допомогою js необхідно змінити подію відправлення форми на свою. Для цього в
ми "слухаємо" всі подіїsubmit на елементі form всередині блоку .products-list , тобто. відправлення форми додавання до кошика товару. Щобзаборонити звичайне відправлення форми ми використовуємо функцію
Далі необхідно надіслати запит до сервера POST. Для цього треба підготувати дані, які надсилатиме. У jQuery є функція serialize() , яка перетворює дані форми в рядок (див. офіційну документацію).
Ось що в нас вийшло:
Т.к. висновок повідомлень користувачу за допомогою javascript нам ще знадобитися, то пропоную зробити функцію setMessage(), щоб не плодити код. Додайте її на початокcart.js :
assets/js/cart.js
І змінимо код додавання до кошика:
assets/js/cart.js
Рада 1
Хорошою практикою є додавання прослуховування події для батьківського елемента. Адже можна було написати й так:
Тут кожної форми додається подіяsubmit. І, коли на сторінці наприклад 1000 товарів, ми додали б 1000 подій, що явно не додасть продуктивності. Так що завжди потрібно додавати саме прослуховування події.
Без прослуховування подій не обійтися, якщо контент динамічно змінюється на сторінці (як у нас кошик. До неї постійно додаються рядки, видаляються, очищаються).
Рада 2
Якщо ви користуєтесь браузером Chrome (а я сподіваюся ви робите це), то напевно вже знаєте про засоби розробника, що викликаються за допомогою клавіші F12. Якщо ні, то давайте спробуємо на нашому кошику простежити за AJAX запитом, який надсилає наш додаток серверу. Відкрийте кошти розробника та перейдіть на вкладку Network (якщо там не порожньо, то очистіть список):
У цьому вікні відображатимуться всі запити до сервера від програми. Тепер натисніть кнопку "Купити". Повинен додатись новий запит, і якщо на нього натиснути, то отримаємо повну інформацію про нього. На скріншоті нижчеможна побачити текст, який повертає сервер:
Якщо відкрити вкладку Headers, можна побачити дані, які ми передаємо серверу, тип відповіді та ще багато інформації, яка дозволить знаходити помилки.
Але доданий товар не з'являється в кошику!
Як ви вже помітили, товар у кошик додається, але не з'являється там. Він з'явиться лише після перезавантаження сторінки. Чому? Так тому що ми не написали javascript функціонал додавання рядка з товаром до кошика.
Реалізовувати це будемо найпростішим способом:
При додаванні товару в кошик, у разі успіху, сервер повертає весь HTML код кошика (з уже доданим до нього рядком нового товару), а ми за допомогою js просто оновимо його.
Цей спосіб простий, але не позбавлений недоліків. Один із них - потрібно отримувати весь HTML кошик, а не тільки ту частину, яку потрібно оновити. Тобто. ми будемо "ганяти" більше трафіку. Але гадаю це не така велика проблема. По-перше, швидкість інтернету дозволяє, по-друге, кошик не такий великий елемент на сторінці, щоб ми відчули якісь гальма в роботі інтерфейсу. По-третє - ви подивіться вихідний код opencart, і код у цій стеті здасться вам ідеальним.
Отже, поправимо трохи код методу add_to_cart() контролера cart. Я не наводитиму повний код методу, тільки невеликий шматок:
application/controllers/cart.php
Після додавання товару в кошик методом $this->cart->insert() , отримуємо в масив $user_cart дані кошика користувача. Далі передаємо цьому пасив шаблон. У результаті весь HTML код кошика зберігатиметься в змінній $cart_html. Впринципі, ми повторили звичайні отримання та виведення кошика, які використовуються в методі index() контролераcart.
Поле цього в масив$result додаємо новий елемент cart_html , в якому буде весь HTML код кошика, і який ми повернемо разом із повідомленням про результат.
Тепер, якщо за допомогою засобів розробка, ми подивимося на результат, який сервер повертає нам після додавання в кошик ми побачимо HTML код кошика:
Далі, за планом – оновлення кошика на сторінці. Ось змінений js код додавання товару до кошика та його оновлення:
Очищаємо кошик
Тут багато вже знайоме. За допомогою стандартного методу
ми очищаємо кошик користувача та виводимо йому повідомлення.
Додамо трохи javascript'a, щоб зробити очищення кошика без перезавантаження сторінки.
Що потрібно зробити:
- За натисканням на кнопку "Очистити кошик" надіслати AJAX запит на сервер
- Після отримання відповіді видалити таблицю з кошиком з DOM
- Вивести повідомлення користувачу.
Приступимо до реалізації:
За подієюsubmit форми очищення кошика, посилаємо AJAX запит на сервер (на URL, який вказаний в атрибуті action форми), потім, якщо сервер повернув статусsuccess, видаляємо таблицю з кошиком, виводимо напис "У кошику немає товарів", і виводимо повідомлення користувачу за допомогою нашої функції setMessage().
Чому я повісив прослуховування події аж на блок .content, а не на, наприклад, .cart. Тому що при очищенні, додаванні товару та його видаленні, ми повністю замінюємо блок .cart і подія з нього "злітає". Тому найближчий батьківський незмінний динамічно елемент до кошика це блок .content.
AJAX видалення товару з кошика
Щоб логічно закінчити статтю, давайте напишемо обробник для кнопок видалення товару з кошика.
- Вішаємо прослуховування події відправки форми з кнопкоювидалення з кошика
- Надсилаємо POST запит на сервер для видалення товару з кошика
- Сервер повертає результат, і, у разі успіху, оновлений HTML кошик.
- За допомогою js ми оновлюємо кошик та виводимо повідомлення користувачу, що товар видалено з кошика
Відкриваємо файлcart.js і пишемо новий зворотник:
assets/js/cart.js
Код дуже схожий на додавання товару до кошика. Ми також збираємо дані форми за допомогою методу $form.serialize() , відсилає дані на URL, який вказаний в атрибуті action форми. Далі, якщо сервер повернувся статусsuccess, оновлюємо кошик і виводить повідомлення користувачу.
Тепер доопрацює код методу видалення товару із кошика delete_item() . Чи здогадуєтеся що потрібно зробити? Отримати дані корзини користувача, пропустити їх через шаблон і повернути у відповіді.
Код для отримання HTML кошика такий самий, як і при оновленні або додаванні товару в кошик:
Лістинг методу delete_item() :
application/controllers/cart.php
Тепер подивимося що вийшло:
На цьому основний це розробки кошика завершено. Далі можна буде вдосконалювати кошик. Наприклад, додати туди:
- Збільшення кількості товару у кошику при повторному додаванні товару до кошика.
- Можливість змінювати кількість товару прямо у блоці з кошиком.
- Рядок із загальною сумою замовлення.
Загалом багато чого. Ви тримаєтеся там, успіхів, удачі.