Step 1: tạo file xử lý Logic trang Tìm kiếm Sản phẩm
- Tạo file
frontend/product/search.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'); /* --- --- 2.Truy vấn dữ liệu Loại Sản phẩm --- */ $sqlSelectLoaiSanPham = <<<EOT SELECT lsp.lsp_ma, lsp.lsp_ten, COUNT(*) soluongsanpham FROM `loaisanpham` lsp LEFT JOIN `sanpham` sp ON lsp.lsp_ma = sp.lsp_ma GROUP BY lsp.lsp_ma, lsp.lsp_ten EOT; // Thực thi câu truy vấn SQL để lấy về dữ liệu ban đầu của record $resultSelectLoaiSanPham = mysqli_query($conn, $sqlSelectLoaiSanPham); // Khi thực thi các truy vấn dạng SELECT, dữ liệu lấy về cần phải phân tích để sử dụng // Thông thường, chúng ta sẽ sử dụng vòng lặp while để duyệt danh sách các dòng dữ liệu được SELECT // Ta sẽ tạo 1 mảng array để chứa các dữ liệu được trả về $loaisanphamData = []; while ($row = mysqli_fetch_array($resultSelectLoaiSanPham, MYSQLI_ASSOC)) { $loaisanphamData[] = array( 'lsp_ma' => $row['lsp_ma'], 'lsp_ten' => $row['lsp_ten'], 'soluongsanpham' => $row['soluongsanpham'], ); } /* --- End Truy vấn dữ liệu Loại Sản phẩm --- */ /* --- --- 3.Truy vấn dữ liệu Nhà sản xuất --- */ $sqlSelectNhaSanXuat = <<<EOT SELECT nsx.nsx_ma, nsx.nsx_ten, COUNT(*) soluongsanpham FROM `nhasanxuat`nsx LEFT JOIN `sanpham` sp ON nsx.nsx_ma = sp.nsx_ma GROUP BY nsx.nsx_ma, nsx.nsx_ten EOT; // Thực thi câu truy vấn SQL để lấy về dữ liệu ban đầu của record $resultSelectNhaSanXuat = mysqli_query($conn, $sqlSelectNhaSanXuat); // Khi thực thi các truy vấn dạng SELECT, dữ liệu lấy về cần phải phân tích để sử dụng // Thông thường, chúng ta sẽ sử dụng vòng lặp while để duyệt danh sách các dòng dữ liệu được SELECT // Ta sẽ tạo 1 mảng array để chứa các dữ liệu được trả về $nhasanxuatData = []; while ($row = mysqli_fetch_array($resultSelectNhaSanXuat, MYSQLI_ASSOC)) { $nhasanxuatData[] = array( 'nsx_ma' => $row['nsx_ma'], 'nsx_ten' => $row['nsx_ten'], 'soluongsanpham' => $row['soluongsanpham'], ); } /* --- End Truy vấn dữ liệu Nhà sản xuất --- */ /* --- --- 4.Truy vấn dữ liệu Khuyến mãi --- */ $sqlSelectKhuyenMai = <<<EOT SELECT km.km_ma, km.km_ten, km_noidung, km_tungay, km_denngay, COUNT(*) soluongsanpham FROM `khuyenmai` km LEFT JOIN `sanpham` sp ON km.km_ma = sp.km_ma GROUP BY km.km_ma, km.km_ten, km_noidung, km_tungay, km_denngay EOT; // Thực thi câu truy vấn SQL để lấy về dữ liệu ban đầu của record $resultSelectKhuyenMai = mysqli_query($conn, $sqlSelectKhuyenMai); // Khi thực thi các truy vấn dạng SELECT, dữ liệu lấy về cần phải phân tích để sử dụng // Thông thường, chúng ta sẽ sử dụng vòng lặp while để duyệt danh sách các dòng dữ liệu được SELECT // Ta sẽ tạo 1 mảng array để chứa các dữ liệu được trả về $khuyenmaiData = []; while ($row = mysqli_fetch_array($resultSelectKhuyenMai, MYSQLI_ASSOC)) { $khuyenmaiData[] = array( 'km_ma' => $row['km_ma'], 'km_ten' => $row['km_ten'], 'km_noidung' => $row['km_noidung'], 'km_tungay' => $row['km_tungay'], 'km_denngay' => $row['km_denngay'], 'soluongsanpham' => $row['soluongsanpham'], ); } /* --- End Truy vấn dữ liệu Nhà sản xuất --- */ /* --- --- 5.Truy vấn dữ liệu Sản phẩm theo keyword tìm kiếm --- */ // Giữ lại keyword mà người dùng tìm kiếm $keyword_tensanpham = isset($_GET['keyword_tensanpham']) ? $_GET['keyword_tensanpham'] : ''; $keyword_loaisanpham = isset($_GET['keyword_loaisanpham']) ? $_GET['keyword_loaisanpham'] : []; $keyword_nhasanxuat = isset($_GET['keyword_nhasanxuat']) ? $_GET['keyword_nhasanxuat'] : []; $keyword_khuyenmai = isset($_GET['keyword_khuyenmai']) ? $_GET['keyword_khuyenmai'] : []; $keyword_sotientu = isset($_GET['keyword_sotientu']) ? $_GET['keyword_sotientu'] : 0; $keyword_sotienden = isset($_GET['keyword_sotienden']) ? $_GET['keyword_sotienden'] : 50000000; // Câu lệnh query động tùy theo yêu cầu tìm kiếm của người dùng $sqlDanhSachSanPham = <<<EOT SELECT sp.sp_ma, sp.sp_ten, sp.sp_gia, sp.sp_giacu, sp.sp_mota_ngan, sp.sp_soluong, lsp.lsp_ten, MAX(hsp.hsp_tentaptin) AS hsp_tentaptin FROM `sanpham` sp JOIN `loaisanpham` lsp ON sp.lsp_ma = lsp.lsp_ma LEFT JOIN `hinhsanpham` hsp ON sp.sp_ma = hsp.sp_ma LEFT JOIN `nhasanxuat` nsx ON sp.nsx_ma = nsx.nsx_ma LEFT JOIN `khuyenmai` km ON sp.km_ma = km.km_ma EOT; // Tìm theo tên sản phẩm $sqlWhereArr = []; if (!empty($keyword_tensanpham)) { $sqlWhereArr[] = "sp.sp_ten LIKE '%$keyword_tensanpham%'"; } // Tìm theo loại sản phẩm if (!empty($keyword_loaisanpham)) { $value = implode(',', $keyword_loaisanpham); $sqlWhereArr[] = "lsp.lsp_ma IN ($value)"; } // Tìm theo nhà sản xuất if (!empty($keyword_nhasanxuat)) { $value = implode(',', $keyword_nhasanxuat); $sqlWhereArr[] = "nsx.nsx_ma IN ($value)"; } // Tìm theo khuyến mãi if (!empty($keyword_khuyenmai)) { $value = implode(',', $keyword_khuyenmai); $sqlWhereArr[] = "km.km_ma IN ($value)"; } // Tìm theo khoảng giá tiền if (!empty($keyword_sotientu) && !empty($keyword_sotienden)) { $sqlWhereArr[] = "sp.sp_gia BETWEEN $keyword_sotientu AND $keyword_sotienden"; } // Câu lệnh cuối cùng if (count($sqlWhereArr) > 0) { $sqlWhere = "WHERE " . implode(' AND ', $sqlWhereArr); $sqlDanhSachSanPham .= $sqlWhere; } $sqlDanhSachSanPham .= <<<EOT GROUP BY sp.sp_ma, sp.sp_ten, sp.sp_gia, sp.sp_giacu, sp.sp_mota_ngan, sp.sp_soluong, lsp.lsp_ten EOT; // Thực thi câu truy vấn SQL để lấy về dữ liệu $result = mysqli_query($conn, $sqlDanhSachSanPham); // Khi thực thi các truy vấn dạng SELECT, dữ liệu lấy về cần phải phân tích để sử dụng // Thông thường, chúng ta sẽ sử dụng vòng lặp while để duyệt danh sách các dòng dữ liệu được SELECT // Ta sẽ tạo 1 mảng array để chứa các dữ liệu được trả về $dataDanhSachSanPham = []; while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { $dataDanhSachSanPham[] = array( 'sp_ma' => $row['sp_ma'], 'sp_ten' => $row['sp_ten'], 'sp_gia' => number_format($row['sp_gia'], 2, ".", ",") . ' vnđ', 'sp_giacu' => number_format($row['sp_giacu'], 2, ".", ","), 'sp_mota_ngan' => $row['sp_mota_ngan'], 'sp_soluong' => $row['sp_soluong'], 'lsp_ten' => $row['lsp_ten'], 'hsp_tentaptin' => $row['hsp_tentaptin'], ); } // dd($sqlWhereArr, $sqlWhere, $sqlDanhSachSanPham, $dataDanhSachSanPham); // Yêu cầu `Twig` vẽ giao diện được viết trong file `frontend/product/search.html.twig` echo $twig->render( 'frontend/product/search.html.twig', [ // Danh mục tiêu chí tìm kiếm 'danhsachloaisanpham' => $loaisanphamData, 'danhsachnhasanxuat' => $nhasanxuatData, 'danhsachkhuyenmai' => $khuyenmaiData, 'danhsachsanpham' => $dataDanhSachSanPham, // Keyword người dùng đã tìm kiếm 'keyword_tensanpham' => $keyword_tensanpham, 'keyword_loaisanpham' => $keyword_loaisanpham, 'keyword_nhasanxuat' => $keyword_nhasanxuat, 'keyword_khuyenmai' => $keyword_khuyenmai, 'keyword_sotientu' => $keyword_sotientu, 'keyword_sotienden' => $keyword_sotienden, ] );
Step 2: tạo template giao diện trang Tìm kiếm
- Tạo file
templates/frontend/product/search.html.twig
{# Kế thừa layout frontend #} {% extends "frontend/layouts/layout.html.twig" %} {# Nội dung trong block title #} {% block title %} Liên hệ {% endblock %} {# End Nội dung trong block title #} {# Nội dung trong block headline #} {% block headline %} Liên hệ {% endblock %} {# End Nội dung trong block headline #} {# Nội dung trong block content #} {% block content %} <div class="container mt-4"> <form name="frmTimKiem" method="get" action="/project-nentang/frontend/product/search.php"> <h1 class="text-center">Tìm kiếm sản phẩm</h1> <div class="row"> <div class="col col-md-12"> <h5 class="text-center">Cung cấp kiến thức nền tảng về Lập trình, Thiết kế Web, Cơ sở dữ liệu</h5> <h5 class="text-center">Giúp các bạn có niềm tin, hành trang kiến thức vững vàng trên con đường trở thành Nhà phát triển Phần mềm</h5> <div class="text-center"> <button type="button" id="btnReset" class="btn btn-warning">Xóa bộ lọc</button> <button class="btn btn-primary btn-lg">Tìm kiếm <i class="fa fa-forward" aria-hidden="true"></i></button> </div> </div> </div> <div class="row"> <aside class="col-sm-4"> <p>Bộ lọc </p> <div class="card"> <!-- Tìm kiếm theo tên sản phẩm --> <article class="card-group-item"> <header class="card-header"> <h6 class="title">Tên sản phẩm </h6> </header> <div class="filter-content"> <div class="card-body"> <input class="form-control" type="text" placeholder="Tìm kiếm" aria-label="Search" name="keyword_tensanpham" value="{{ keyword_tensanpham ? keyword_tensanpham : '' }}"> </div> <!-- card-body.// --> </div> </article> <!-- // Tìm kiếm theo Tên sản phẩm --> <!-- Tìm kiếm theo Loại sản phẩm --> <article class="card-group-item"> <header class="card-header"> <h6 class="title">Loại sản phẩm </h6> </header> <div class="filter-content"> <div class="card-body"> {% for loaisanpham in danhsachloaisanpham %} <div class="custom-control custom-checkbox"> <span class="float-right badge badge-light round">{{ loaisanpham.soluongsanpham }}</span> <input type="checkbox" class="custom-control-input" name="keyword_loaisanpham[]" value="{{ loaisanpham.lsp_ma }}" id="chk-loaisanpham-{{ loaisanpham.lsp_ma }}" {{ (loaisanpham.lsp_ma in keyword_loaisanpham) ? 'checked' : '' }}> <label class="custom-control-label" for="chk-loaisanpham-{{ loaisanpham.lsp_ma }}">{{ loaisanpham.lsp_ten }}</label> </div> <!-- form-check.// --> {% endfor %} </div> <!-- card-body.// --> </div> </article> <!-- // Tìm kiếm theo Loại sản phẩm --> <!-- Tìm kiếm theo Nhà sản xuất --> <article class="card-group-item"> <header class="card-header"> <h6 class="title">Nhà sản xuất </h6> </header> <div class="filter-content"> <div class="card-body"> {% for nhasanxuat in danhsachnhasanxuat %} <div class="custom-control custom-checkbox"> <span class="float-right badge badge-light round">{{ nhasanxuat.soluongsanpham }}</span> <input type="checkbox" class="custom-control-input" name="keyword_nhasanxuat[]" value="{{ nhasanxuat.nsx_ma }}" id="chk-nhasanxuat-{{ nhasanxuat.nsx_ma }}" {{ (nhasanxuat.nsx_ma in keyword_nhasanxuat) ? 'checked' : '' }}> <label class="custom-control-label" for="chk-nhasanxuat-{{ nhasanxuat.nsx_ma }}">{{ nhasanxuat.nsx_ten }}</label> </div> <!-- form-check.// --> {% endfor %} </div> <!-- card-body.// --> </div> </article> <!-- // Tìm kiếm theo Nhà sản xuất --> <!-- Tìm kiếm theo Khuyến mãi --> <article class="card-group-item"> <header class="card-header"> <h6 class="title">Khuyến mãi </h6> </header> <div class="filter-content"> <div class="card-body"> {% for khuyenmai in danhsachkhuyenmai %} <div class="custom-control custom-checkbox"> <span class="float-right badge badge-light round">{{ khuyenmai.soluongsanpham }}</span> <input type="checkbox" class="custom-control-input" name="keyword_khuyenmai[]" value="{{ khuyenmai.km_ma }}" id="chk-khuyenmai-{{ khuyenmai.km_ma }}" {{ (khuyenmai.km_ma in keyword_khuyenmai) ? 'checked' : '' }}> <label class="custom-control-label" for="chk-khuyenmai-{{ khuyenmai.km_ma }}">{{ khuyenmai.km_ten }}</label> </div> <!-- form-check.// --> {% endfor %} </div> <!-- card-body.// --> </div> </article> <!-- // Tìm kiếm theo Nhà sản xuất --> <!-- Tìm kiếm theo khoảng giá tiền --> <article class="card-group-item"> <header class="card-header"> <h6 class="title">Khoảng tiền </h6> </header> <div class="filter-content"> <div class="card-body"> <div class="form-row"> <div class="form-group col-md-6"> <label>Từ</label> <input type="range" class="custom-range" min="0" max="50000000" step="100000" id="sotientu" name="keyword_sotientu" value="{{ keyword_sotientu ? keyword_sotientu : 0 }}"> <span><span id="sotientu-text"></span></span> </div> <div class="form-group col-md-6 text-right"> <label>Đến</label> <input type="range" class="custom-range" min="0" max="50000000" step="100000" id="sotienden" name="keyword_sotienden" value="{{ keyword_sotienden ? keyword_sotienden : 50000000 }}"> <span><span id="sotienden-text"></span></span> </div> </div> </div> <!-- card-body.// --> </div> </article> <!-- // Tìm kiếm theo khoảng giá tiền --> <!-- Tìm kiếm theo màu sắc sản phẩm --> <article class="card-group-item"> <header class="card-header"> <h6 class="title">Màu sắc (tùy chọn thêm)</h6> </header> <div class="filter-content"> <div class="card-body"> <label class="btn btn-danger"> <input class="" type="checkbox" value=""> <span class="form-check-label">Đỏ</span> </label> <label class="btn btn-success"> <input class="" type="checkbox" value=""> <span class="form-check-label">Xanh lá</span> </label> <label class="btn btn-primary"> <input class="" type="checkbox" value=""> <span class="form-check-label">Xanh dương</span> </label> </div> <!-- card-body.// --> </div> </article> <!-- // Tìm kiếm theo màu sắc sản phẩm --> </div> <!-- card.// --> </aside> <!-- col.// --> <!-- Giải thuật duyệt và render Danh sách sản phẩm theo dòng, cột của Bootstrap --> {% set counter = 0 %} {% set group = 2 %} {% set limit = danhsachsanpham|length %} {% set col_class_name = (12 / group) %} <div class="col-sm-8 mt-2"> <div class="row"> <div class="col-md-12"> <h6>Tìm kiếm được {{ danhsachsanpham|length }} sản phẩm</h6> </div> </div> <div class="row"> {% if danhsachsanpham|length >0 %} {% for sanpham in danhsachsanpham %} <div class="col-md-{{ col_class_name }}"> <div class="card mb-4 shadow-sm"> {% if sanpham.hsp_tentaptin %} <a href="/project-nentang/frontend/sanpham/chitiet?sp_ma={{ sanpham.sp_ma }}"> <img class="bd-placeholder-img card-img-top" width="100%" height="350" src="/project-nentang/assets/uploads/{{ sanpham.hsp_tentaptin }}" /> </a> {% else %} <a href="/project-nentang/frontend/sanpham/chitiet?sp_ma={{ sanpham.sp_ma }}"> <img class="bd-placeholder-img card-img-top" width="100%" height="350" src="/project-nentang/assets/shared/img/default-image_600.png" /> </a> {% endif %} <div class="card-body"> <a href="/project-nentang/frontend/sanpham/chitiet?sp_ma={{ sanpham.sp_ma }}"> <h5>{{ sanpham.sp_ten }}</h5> </a> <h6>{{ sanpham.lsp_ten }}</h6> <p class="card-text">{{ sanpham.sp_mota_ngan }}</p> <div class="d-flex justify-content-between align-items-center"> <div class="btn-group"> <a class="btn btn-sm btn-outline-secondary" href="/project-nentang/frontend/sanpham/chitiet?sp_ma={{ sanpham.sp_ma }}">Xem chi tiết</a> </div> <small class="text-muted text-right"> <s>{{ sanpham.sp_giacu }}</s> <b>{{ sanpham.sp_gia }}</b> </small> </div> </div> </div> </div> {% set counter = counter + 1 %} {% if (counter % group == 0 and counter < limit) %} </div> <div class="row"> {% endif %} {% endfor %} {% else %} <div class="col-md-12"> <h2>Xin lỗi, không tìm thấy sản phẩm nào theo yêu cầu!</h2> </div> {% endif %} </div> </div> </div> <!-- row.// --> </form> </div> {% endblock %} {# End Nội dung trong block content #} {% block customscripts %} <script> $(document).ready(function () { $('#sotientu').on('change', function (e) { var id = e.target.value; document.getElementById("sotientu-text").innerHTML = id; }); $('#sotientu').change(); $('#sotienden').on('change', function (e) { var id = e.target.value; document.getElementById("sotienden-text").innerHTML = id; }); $('#sotienden').change(); function clearForm() { var frm_elements = frmTimKiem.elements; for (i = 0; i < frm_elements.length; i++) { field_type = frm_elements[i].type.toLowerCase(); switch (field_type) { case "text": case "password": case "textarea": case "hidden": frm_elements[i].value = ""; break; case "radio": case "checkbox": if (frm_elements[i].checked) { frm_elements[i].checked = false; } break; case "select-one": case "select-multi": frm_elements[i].selectedIndex = -1; break; case "range": if (frm_elements[i].name == 'keyword_sotientu') { frm_elements[i].value = frm_elements[i].min; document.getElementById("sotientu-text").innerHTML = frm_elements[i].min; } else if (frm_elements[i].name == 'keyword_sotienden') { frm_elements[i].value = frm_elements[i].max; document.getElementById("sotienden-text").innerHTML = frm_elements[i].max; } break; default: break; } } } $('#btnReset').click(function (e) { clearForm(); }); }); </script> {% endblock %}
Chương trình học
Các bài học
Bài học trước
Chương trình học
Bao gồm Module, Chương, Bài học, Bài tập, Kiểm tra...Chương trình học
Bài học trước