Learn how to create an AJAX-based cart system in CodeIgniter 4 by building a custom cart library and integrating it seamlessly into your project. This step-by-step guide will help you add, update, and remove cart items dynamically with a clean and efficient setup.
Step 1: Create the Custom Cart Library
The first step is to create a library to handle cart operations.
File: app/Libraries/CartSystem/Cart.php
<?php
namespace App\Libraries\CartSystem;
class Cart
{
protected $cart = [];
public function addItem(array $item)
{
$id = $item['id'];
if (isset($this->cart[$id])) {
$this->cart[$id]['quantity'] += $item['quantity'];
} else {
$this->cart[$id] = $item;
}
}
public function updateItem($id, $quantity)
{
if (isset($this->cart[$id])) {
if ($quantity > 0) {
$this->cart[$id]['quantity'] = $quantity;
} else {
unset($this->cart[$id]);
}
}
}
public function removeItem($id)
{
unset($this->cart[$id]);
}
public function getCart()
{
return $this->cart;
}
public function getTotal()
{
$total = 0;
foreach ($this->cart as $item) {
$total += $item['price'] * $item['quantity'];
}
return $total;
}
public function clearCart()
{
$this->cart = [];
}
}
Step 2: Create the Cart Controller
The controller will handle AJAX requests for adding, updating, removing, and fetching cart data.
File: app/Controllers/CartController.php
<?php
namespace App\Controllers;
use App\Libraries\CartSystem\Cart;
class CartController extends BaseController
{
protected $cart;
public function __construct()
{
$this->cart = new Cart();
}
public function add()
{
$item = [
'id' => $this->request->getPost('product_id'),
'name' => $this->request->getPost('name'),
'price' => $this->request->getPost('unit_price'),
'quantity' => $this->request->getPost('quantity'),
];
$this->cart->addItem($item);
return $this->response->setJSON([
'status' => 'success',
'cart' => $this->cart->getCart(),
'total' => $this->cart->getTotal(),
]);
}
public function update()
{
$id = $this->request->getPost('product_id');
$quantity = $this->request->getPost('quantity');
$this->cart->updateItem($id, $quantity);
return $this->response->setJSON([
'status' => 'success',
'cart' => $this->cart->getCart(),
'total' => $this->cart->getTotal(),
]);
}
public function remove()
{
$id = $this->request->getPost('product_id');
$this->cart->removeItem($id);
return $this->response->setJSON([
'status' => 'success',
'cart' => $this->cart->getCart(),
'total' => $this->cart->getTotal(),
]);
}
public function fetch()
{
return $this->response->setJSON([
'status' => 'success',
'cart' => $this->cart->getCart(),
'total' => $this->cart->getTotal(),
]);
}
Step 3: Configure Routes
Add routes to handle cart operations in app/Config/Routes.php
:
$routes->post('cart/add', 'CartController::add');
$routes->post('cart/update', 'CartController::update');
$routes->post('cart/remove', 'CartController::remove');
$routes->get('cart/fetch', 'CartController::fetch');
Step 4: Create the Frontend Form
Use the following HTML form for adding products to the cart:
<div class="col-lg-4">
<form id="addSaleForm">
<div class="card">
<div class="card-header">
<h5>Add Sale</h5>
</div>
<div class="card-body">
<input type="hidden" id="product_id" name="product_id">
<input type="text" id="name" name="name" placeholder="Product Name" readonly>
<input type="number" id="quantity" name="quantity" placeholder="Quantity">
<input type="text" id="unit_price" name="unit_price" placeholder="Unit Price" readonly>
<button type="button" id="submitSale">Add to Cart</button>
</div>
</div>
</form>
</div>
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<h5>Cart Items</h5>
</div>
<div class="card-body" id="cartItems"></div>
<div class="card-footer">Total: <span id="cartTotal">0.00</span></div>
</div>
</div>
Step 5: Add JavaScript for AJAX
Integrate AJAX to handle cart operations dynamically:
$(document).ready(function () {
$("#submitSale").click(function () {
const item = {
product_id: $("#product_id").val(),
name: $("#name").val(),
unit_price: parseFloat($("#unit_price").val()),
quantity: parseInt($("#quantity").val()),
};
$.post('/cart/add', item, function (response) {
updateCartView(response.cart, response.total);
});
});
function updateCartView(cart, total) {
const cartItems = $('#cartItems');
cartItems.empty();
cart.forEach(item => {
cartItems.append(`<div>${item.name} x ${item.quantity} - ${item.price}</div>`);
});
$('#cartTotal').text(total);
}
});