Step 1: tạo file Logic hiển thị thông tin Giỏ hàng

  • Tạo file frontend/checkout/cart.php
<?php
// Include file cấu hình ban đầu của `Twig`
require_once __DIR__ . '/../../bootstrap.php';
// Truy vấn database để lấy danh sách
// 1. Include file cấu hình kết nối đến database, khởi tạo kết nối $conn
include_once(__DIR__ . '/../../dbconnect.php');
// Kiểm tra dữ liệu trong session
$data = [];
if (isset($_SESSION['giohangdata'])) {
$data = $_SESSION['giohangdata'];
} else {
$data = [];
}
// Yêu cầu `Twig` vẽ giao diện được viết trong file `frontend/thanhtoan/giohang.html.twig`
// với dữ liệu truyền vào file giao diện được đặt tên là `giohangdata`
// dd($data);
echo $twig->render('frontend/thanhtoan/giohang.html.twig', ['giohangdata' => $data]);
<?php // Include file cấu hình ban đầu của `Twig` require_once __DIR__ . '/../../bootstrap.php'; // Truy vấn database để lấy danh sách // 1. Include file cấu hình kết nối đến database, khởi tạo kết nối $conn include_once(__DIR__ . '/../../dbconnect.php'); // Kiểm tra dữ liệu trong session $data = []; if (isset($_SESSION['giohangdata'])) { $data = $_SESSION['giohangdata']; } else { $data = []; } // Yêu cầu `Twig` vẽ giao diện được viết trong file `frontend/thanhtoan/giohang.html.twig` // với dữ liệu truyền vào file giao diện được đặt tên là `giohangdata` // dd($data); echo $twig->render('frontend/thanhtoan/giohang.html.twig', ['giohangdata' => $data]);
<?php
// Include file cấu hình ban đầu của `Twig`
require_once __DIR__ . '/../../bootstrap.php';

// Truy vấn database để lấy danh sách
// 1. Include file cấu hình kết nối đến database, khởi tạo kết nối $conn
include_once(__DIR__ . '/../../dbconnect.php');

// Kiểm tra dữ liệu trong session
$data = [];
if (isset($_SESSION['giohangdata'])) {
    $data = $_SESSION['giohangdata'];
} else { 
    $data = [];
}

// Yêu cầu `Twig` vẽ giao diện được viết trong file `frontend/thanhtoan/giohang.html.twig`
// với dữ liệu truyền vào file giao diện được đặt tên là `giohangdata`
// dd($data);
echo $twig->render('frontend/thanhtoan/giohang.html.twig', ['giohangdata' => $data]);

Step 2: tạo file template giao diện Giỏ hàng

  • Tạo file templates/frontend/checkout/giohang.html.twig
{# Kế thừa layout frontend #}
{% extends "frontend/layouts/layout.html.twig" %}
{# Nội dung trong block title #}
{% block title %}
Giỏ hàng
{% endblock %}
{# End Nội dung trong block title #}
{# Nội dung trong block headline #}
{% block headline %}
Giỏ hàng
{% endblock %}
{# End Nội dung trong block headline #}
{% block customstyles %}
<style>
.hinhdaidien {
width: 150px;
height: 150px;
}
</style>
{% endblock %}
{# Nội dung trong block content #}
{% block content %}
<div class="container mt-4">
<div id="errors-container" class="alert alert-danger d-none face" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<h1 class="text-center">Giỏ hàng</h1>
<div class="row">
<div class="col col-md-12">
{% if giohangdata %}
<table class="table table-bordered">
<thead>
<tr>
<th>STT</th>
<th>Ảnh đại diện</th>
<th>Tên sản phẩm</th>
<th>Số lượng</th>
<th>Đơn giá</th>
<th>Thành tiền</th>
<th>Hành động</th>
</tr>
</thead>
<tbody id="datarow">
{% for sanpham in giohangdata %}
<tr>
<td>{{ loop.index }}</td>
<td>
{% if sanpham.hinhdaidien %}
<img src="/project-nentang/assets/uploads/{{ sanpham.hinhdaidien }}" class="hinhdaidien" />
{% else %}
<img src="/project-nentang/assets/shared/img/default-image_600.png" class="hinhdaidien" />
{% endif %}
</td>
<td>{{ sanpham.sp_ten }}</td>
<td>
<input type="number" id="soluong_{{ sanpham.sp_ma }}" name="soluong" value="{{ sanpham.soluong }}" />
<button class="btn btn-primary btn-sm btn-capnhat-soluong" data-sp-ma="{{ sanpham.sp_ma }}">Cập nhật</button>
</td>
<td>{{ sanpham.gia }}</td>
<td>{{ sanpham.soluong * sanpham.gia }}</td>
<td>
<!-- Nút xóa, bấm vào sẽ xóa thông tin dựa vào khóa chính `sp_ma` -->
<a id="delete_{{ loop.index }}" data-sp-ma="{{ sanpham.sp_ma }}" class="btn btn-danger btn-delete-sanpham">
<i class="fa fa-trash" aria-hidden="true"></i> Xóa
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h2>Giỏ hàng rỗng!!!</h2>
{% endif %}
<a href="/" class="btn btn-warning btn-md"><i class="fa fa-arrow-left" aria-hidden="true"></i>&nbsp;Quay
về trang chủ</a>
<a href="/frontend/thanhtoan/thanhtoan" class="btn btn-primary btn-md"><i class="fa fa-shopping-cart"
aria-hidden="true"></i>&nbsp;Thanh toán</a>
</div>
</div>
</div>
{% endblock %}
{# End Nội dung trong block content #}
{% block customscripts %}
<script>
$(document).ready(function () {
function removeSanPhamVaoGioHang(id) {
var dulieugoi = {
sp_ma: id
};
$.ajax({
url: '/project-nentang/frontend/ajax/giohang-xoasanpham-ajax.php',
method: "POST",
dataType: 'json',
data: dulieugoi,
success: function (data) {
// Refresh lại trang
location.reload();
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
var htmlString = `<h1>Không thể xử lý</h1>`;
$('#thongbao').html(htmlString);
// Hiện thông báo
$('.alert').removeClass('d-none').addClass('show');
}
});
};
$('.btn-delete-sanpham').on('click', function (event) {
event.preventDefault();
var id = $(this).data('sp-ma');
console.log(id);
removeSanPhamVaoGioHang(id);
});
function capnhatSanPhamTrongGioHang(id, soluong) {
var dulieugoi = {
sp_ma: id,
soluong: soluong
};
$.ajax({
url: '/project-nentang/frontend/ajax/giohang-capnhatsanpham-ajax.php',
method: "POST",
dataType: 'json',
data: dulieugoi,
success: function (data) {
// Refresh lại trang
location.reload();
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
var htmlString = `<h1>Không thể xử lý</h1>`;
$('#thongbao').html(htmlString);
// Hiện thông báo
$('.alert').removeClass('d-none').addClass('show');
}
});
};
$('.btn-capnhat-soluong').on('click', function(event) {
event.preventDefault();
var id = $(this).data('sp-ma');
var soluongmoi = $('#soluong_' + id).val();
capnhatSanPhamTrongGioHang(id, soluongmoi);
});
});
</script>
{% endblock %}
{# Kế thừa layout frontend #} {% extends "frontend/layouts/layout.html.twig" %} {# Nội dung trong block title #} {% block title %} Giỏ hàng {% endblock %} {# End Nội dung trong block title #} {# Nội dung trong block headline #} {% block headline %} Giỏ hàng {% endblock %} {# End Nội dung trong block headline #} {% block customstyles %} <style> .hinhdaidien { width: 150px; height: 150px; } </style> {% endblock %} {# Nội dung trong block content #} {% block content %} <div class="container mt-4"> <div id="errors-container" class="alert alert-danger d-none face" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> </div> <h1 class="text-center">Giỏ hàng</h1> <div class="row"> <div class="col col-md-12"> {% if giohangdata %} <table class="table table-bordered"> <thead> <tr> <th>STT</th> <th>Ảnh đại diện</th> <th>Tên sản phẩm</th> <th>Số lượng</th> <th>Đơn giá</th> <th>Thành tiền</th> <th>Hành động</th> </tr> </thead> <tbody id="datarow"> {% for sanpham in giohangdata %} <tr> <td>{{ loop.index }}</td> <td> {% if sanpham.hinhdaidien %} <img src="/project-nentang/assets/uploads/{{ sanpham.hinhdaidien }}" class="hinhdaidien" /> {% else %} <img src="/project-nentang/assets/shared/img/default-image_600.png" class="hinhdaidien" /> {% endif %} </td> <td>{{ sanpham.sp_ten }}</td> <td> <input type="number" id="soluong_{{ sanpham.sp_ma }}" name="soluong" value="{{ sanpham.soluong }}" /> <button class="btn btn-primary btn-sm btn-capnhat-soluong" data-sp-ma="{{ sanpham.sp_ma }}">Cập nhật</button> </td> <td>{{ sanpham.gia }}</td> <td>{{ sanpham.soluong * sanpham.gia }}</td> <td> <!-- Nút xóa, bấm vào sẽ xóa thông tin dựa vào khóa chính `sp_ma` --> <a id="delete_{{ loop.index }}" data-sp-ma="{{ sanpham.sp_ma }}" class="btn btn-danger btn-delete-sanpham"> <i class="fa fa-trash" aria-hidden="true"></i> Xóa </a> </td> </tr> {% endfor %} </tbody> </table> {% else %} <h2>Giỏ hàng rỗng!!!</h2> {% endif %} <a href="/" class="btn btn-warning btn-md"><i class="fa fa-arrow-left" aria-hidden="true"></i>&nbsp;Quay về trang chủ</a> <a href="/frontend/thanhtoan/thanhtoan" class="btn btn-primary btn-md"><i class="fa fa-shopping-cart" aria-hidden="true"></i>&nbsp;Thanh toán</a> </div> </div> </div> {% endblock %} {# End Nội dung trong block content #} {% block customscripts %} <script> $(document).ready(function () { function removeSanPhamVaoGioHang(id) { var dulieugoi = { sp_ma: id }; $.ajax({ url: '/project-nentang/frontend/ajax/giohang-xoasanpham-ajax.php', method: "POST", dataType: 'json', data: dulieugoi, success: function (data) { // Refresh lại trang location.reload(); }, error: function (jqXHR, textStatus, errorThrown) { console.log(textStatus, errorThrown); var htmlString = `<h1>Không thể xử lý</h1>`; $('#thongbao').html(htmlString); // Hiện thông báo $('.alert').removeClass('d-none').addClass('show'); } }); }; $('.btn-delete-sanpham').on('click', function (event) { event.preventDefault(); var id = $(this).data('sp-ma'); console.log(id); removeSanPhamVaoGioHang(id); }); function capnhatSanPhamTrongGioHang(id, soluong) { var dulieugoi = { sp_ma: id, soluong: soluong }; $.ajax({ url: '/project-nentang/frontend/ajax/giohang-capnhatsanpham-ajax.php', method: "POST", dataType: 'json', data: dulieugoi, success: function (data) { // Refresh lại trang location.reload(); }, error: function (jqXHR, textStatus, errorThrown) { console.log(textStatus, errorThrown); var htmlString = `<h1>Không thể xử lý</h1>`; $('#thongbao').html(htmlString); // Hiện thông báo $('.alert').removeClass('d-none').addClass('show'); } }); }; $('.btn-capnhat-soluong').on('click', function(event) { event.preventDefault(); var id = $(this).data('sp-ma'); var soluongmoi = $('#soluong_' + id).val(); capnhatSanPhamTrongGioHang(id, soluongmoi); }); }); </script> {% endblock %}
{# Kế thừa layout frontend #}
{% extends "frontend/layouts/layout.html.twig" %}

{# Nội dung trong block title #}
{% block title %}
Giỏ hàng
{% endblock %}
{# End Nội dung trong block title #}

{# Nội dung trong block headline #}
{% block headline %}
Giỏ hàng
{% endblock %}
{# End Nội dung trong block headline #}

{% block customstyles %}
<style>
    .hinhdaidien {
        width: 150px;
        height: 150px;
    }
</style>
{% endblock %}

{# Nội dung trong block content #}
{% block content %}
<div class="container mt-4">
    <div id="errors-container" class="alert alert-danger d-none face" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>

    <h1 class="text-center">Giỏ hàng</h1>
    <div class="row">
        <div class="col col-md-12">
            {% if giohangdata %}
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th>STT</th>
                        <th>Ảnh đại diện</th>
                        <th>Tên sản phẩm</th>
                        <th>Số lượng</th>
                        <th>Đơn giá</th>
                        <th>Thành tiền</th>
                        <th>Hành động</th>
                    </tr>
                </thead>
                <tbody id="datarow">
                    {% for sanpham in giohangdata %}
                    <tr>
                        <td>{{ loop.index }}</td>
                        <td>
                            {% if sanpham.hinhdaidien %}
                            <img src="/project-nentang/assets/uploads/{{ sanpham.hinhdaidien }}" class="hinhdaidien" />
                            {% else %}
                            <img src="/project-nentang/assets/shared/img/default-image_600.png" class="hinhdaidien" />
                            {% endif %}
                        </td>
                        <td>{{ sanpham.sp_ten }}</td>
                        <td>
                            <input type="number" id="soluong_{{ sanpham.sp_ma }}" name="soluong" value="{{ sanpham.soluong }}" />
                            <button class="btn btn-primary btn-sm btn-capnhat-soluong" data-sp-ma="{{ sanpham.sp_ma }}">Cập nhật</button>
                        </td>
                        <td>{{ sanpham.gia }}</td>
                        <td>{{ sanpham.soluong * sanpham.gia }}</td>
                        <td>
                            <!-- Nút xóa, bấm vào sẽ xóa thông tin dựa vào khóa chính `sp_ma` -->
                            <a id="delete_{{ loop.index }}" data-sp-ma="{{ sanpham.sp_ma }}" class="btn btn-danger btn-delete-sanpham">
                                <i class="fa fa-trash" aria-hidden="true"></i> Xóa
                            </a>
                        </td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
            {% else %}
            <h2>Giỏ hàng rỗng!!!</h2>
            {% endif %}

            <a href="/" class="btn btn-warning btn-md"><i class="fa fa-arrow-left" aria-hidden="true"></i>&nbsp;Quay
                về trang chủ</a>
            <a href="/frontend/thanhtoan/thanhtoan" class="btn btn-primary btn-md"><i class="fa fa-shopping-cart"
                    aria-hidden="true"></i>&nbsp;Thanh toán</a>
        </div>
    </div>
</div>
{% endblock %}
{# End Nội dung trong block content #}

{% block customscripts %}
<script>
    $(document).ready(function () {
        function removeSanPhamVaoGioHang(id) {
            var dulieugoi = {
                sp_ma: id
            };
            $.ajax({
                url: '/project-nentang/frontend/ajax/giohang-xoasanpham-ajax.php',
                method: "POST",
                dataType: 'json',
                data: dulieugoi,
                success: function (data) {
                    // Refresh lại trang
                    location.reload();
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log(textStatus, errorThrown);
                    var htmlString = `<h1>Không thể xử lý</h1>`;
                    $('#thongbao').html(htmlString);
                    // Hiện thông báo
                    $('.alert').removeClass('d-none').addClass('show');
                }
            });
        };
        $('.btn-delete-sanpham').on('click', function (event) {
            event.preventDefault();

            var id = $(this).data('sp-ma');
            
            console.log(id);
            removeSanPhamVaoGioHang(id);
        });


        function capnhatSanPhamTrongGioHang(id, soluong) {
            var dulieugoi = {
                sp_ma: id,
                soluong: soluong
            };
            $.ajax({
                url: '/project-nentang/frontend/ajax/giohang-capnhatsanpham-ajax.php',
                method: "POST",
                dataType: 'json',
                data: dulieugoi,
                success: function (data) {
                    // Refresh lại trang
                    location.reload();
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log(textStatus, errorThrown);
                    var htmlString = `<h1>Không thể xử lý</h1>`;
                    $('#thongbao').html(htmlString);
                    // Hiện thông báo
                    $('.alert').removeClass('d-none').addClass('show');
                }
            });
        };
        $('.btn-capnhat-soluong').on('click', function(event) {
            event.preventDefault();

            var id = $(this).data('sp-ma');
            var soluongmoi = $('#soluong_' + id).val();

            capnhatSanPhamTrongGioHang(id, soluongmoi);
        });
    });
</script>
{% endblock %}