Nền tảng Kiến thức - Hành trang tới Tương lai
Card image

Chương trình học


  1. Bức tranh Tổng thể về Lập trình WEB
  2. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế Backend 1
    1. Xây dựng chức năng CRUD Master Detail - Đơn hàng - Index

Chương 2 - Bài 1. Xây dựng chức năng CRUD Master Detail - Đơn hàng - Index

Tác giả: Dương Nguyễn Phú Cường
Ngày đăng: Hồi xưa đó

Yêu cầu cần có khi thực hiện chức năng

  • Cần phải có table orders và table order_detail. Nếu chưa có table, vui lòng xem lại bài tạo cấu trúc database bằng migration.
  • Cần phải có model Order và model HinhAnh. Chúng ta sẽ thực hiện truy vấn database dựa trên model. Nếu chưa có model, vui lòng xem lại bài học tạo model

Chức năng cần thực hiện

Cần tạo chức năng dành cho Quản trị Hệ thống (Admin) quản lý Đơn hàng. Câu lệnh:
SELECT o.id, COUNT(*)
FROM orders o
JOIN order_details od ON od.order_id = o.id
GROUP BY o.id

-- Id đơn hàng, Mã đơn hàng, Thông tin khách hàng, Thông tin tóm tắt Đơn hàng
Mã đơn hàng Thông tin Khách hàng Ngày đặt hàng Đã giao hàng vào lúc Thông tin tóm tắt Đơn hàng Hành động
ĐH001 Dương Nguyễn Phú Cường Công ty TNHH MTV ABC Điện thoại: 0915659223 Địa chỉ: 130 Xô Viết Nghệ Tỉnh, Quận Ninh Kiều, TP Cần Thơ   27/08/2019 14:59 Chưa giao :( 3 mặt hàng Tổng thành tiền: 15.000.000đ [Sửa] - [Xóa]
...
 

Cách thực hiện

Step 1: tạo các routes Danh mục sản phẩm

  • Hiệu chỉnh file routes/web.php
// route Danh mục Sản phẩm
Route::resource('/admin/danhsachsanpham', 'SanPhamController');
  • Kiểm tra các route bằng câu lệnh:
php artisan route:list
+--------+-----------+----------------------------------------------+-------------------------+------------------------------------------------+--------------+
| Domain | Method    | URI                                          | Name                    | Action                                         | Middleware   |
+--------+-----------+----------------------------------------------+-------------------------+------------------------------------------------+--------------+
|        | GET|HEAD  | /                                            | home                    | Closure                                        | web          |
|        | GET|HEAD  |
admin/danhsachsanpham
                        |
danhsachsanpham.index
   |
AppHttpControllersSanPhamController@index
     | web          |
|        |
POST | admin/danhsachsanpham | danhsachsanpham.store | AppHttpControllersSanPhamController@store
      | web          |
|        | GET|HEAD  |
admin/danhsachsanpham/create
                 |
danhsachsanpham.create
  | AppHttpControllers
SanPhamController@create
     | web          |
|
| GET|HEAD | admin/danhsachsanpham/{danhsachsanpham}/edit | danhsachsanpham.edit | AppHttpControllersSanPhamController@edit
       | web          |
|
| PUT|PATCH | admin/danhsachsanpham/{danhsachsanpham} | danhsachsanpham.update | AppHttpControllersSanPhamController@update
     | web          |
|        | GET|HEAD  | admin/danhsachsanpham/{danhsachsanpham}      | danhsachsanpham.show    | AppHttpControllersSanPhamController@show       | web          |
|
| DELETE | admin/danhsachsanpham/{danhsachsanpham} | danhsachsanpham.destroy | AppHttpControllersSanPhamController@destroy
    | web          |
+--------+-----------+----------------------------------------------+-------------------------+------------------------------------------------+--------------+
Nếu người dùng (client) gởi các request đến server thì Laravel sẽ điều hướng đến các action cụ thể như bảng trên. Ví dụ:
  • http://tenmiencuaban.com/admin/danhsachsanpham (GET) -> Laravel sẽ điều hướng đến action index() trong controller SanPhamController.
  • http://tenmiencuaban.com/admin/danhsachsanpham/create (GET) -> Laravel sẽ điều hướng đến action create() trong controller SanPhamController.
  • http://tenmiencuaban.com/admin/danhsachsanpham (POST) -> Laravel sẽ điều hướng đến action store() trong controller SanPhamController.
  • http://tenmiencuaban.com/admin/danhsachsanpham/1/edit (GET) -> Laravel sẽ điều hướng đến action edit() trong controller SanPhamController.
  • http://tenmiencuaban.com/admin/danhsachsanpham/1 (PUT/PATCH) -> Laravel sẽ điều hướng đến action update() trong controller SanPhamController.
  • http://tenmiencuaban.com/admin/danhsachsanpham/1 (DELETE) -> Laravel sẽ điều hướng đến action destroy() trong controller SanPhamController.

Step 2: tạo controller chứa các action thực thi các tác vụ CRUD (Thêm, Sửa, Xóa) cho Danh mục Sản phẩm

  • Thực thi câu lệnh
php artisan make:controller SanPhamController --resource
  • Laravel Framework sẽ tạo cho bạn file controller ở appHttpControllersSanphamController.php

Step 3: thực hiện tạo màn hình hiển thị danh sách Sản phẩm (index)

Mô hình hoạt động của index:

Viết code cho action index():

  • Action index() thường dùng để hiển thị màn hình danh sách (theo dạng bảng dòng, cột) các sản phẩm có trong table sanpham
  • Danh sách thường hiển thị dạng Phân trang.
  • Trên màn hình sẽ có nút Thêm Sản phẩm mới
  • Trong mỗi dòng Sản phẩm, sẽ có nút Sửa, Xóa
Hiệu chỉnh file appHttpControllersSanphamController.php
public function index()
{
    // Sử dụng Eloquent Model để truy vấn dữ liệu
    $ds_sanpham = SanPham::all(); // SELECT * FROM sanpham

    // Đường dẫn đến view được quy định như sau: <FolderName>.<ViewName>
    // Mặc định đường dẫn gốc của method view() là thư mục `resources/views`
    // Hiển thị view `sanpham.index`
    return view('sanpham.index')
        // với dữ liệu truyền từ Controller qua View, được đặt tên là `danhsachsanpham`
        ->with('danhsachsanpham', $ds_sanpham);
}
Tạo view index.blade.php
  • Để dễ dàng quản lý các view, ta sẽ tạo 1 thư mục tương ứng với tên Controller, mỗi action sẽ tương ứng với tên view.
  • Tạo folder resources/views/sanpham
  • Tạo file resources/views/sanpham/index.blade.php
{{-- View này sẽ kế thừa giao diện từ `backend.layouts.index` --}}
@extends('backend.layouts.index')

{{-- Thay thế nội dung vào Placeholder `title` của view `backend.layouts.index` --}}
@section('title')
Danh sách sản phẩm
@endsection

{{-- Thay thế nội dung vào Placeholder `main-content` của view `backend.layouts.index` --}}
@section('main-content')
<!-- Đây là div hiển thị Kết quả (thành công, thất bại) sau khi thực hiện các chức năng Thêm, Sửa, Xóa.
- Div này chỉ hiển thị khi trong Session có các key `alert-*` từ Controller trả về. 
- Sử dụng các class của Bootstrap "danger", "warning", "success", "info" để hiển thị màu cho đúng với trạng thái kết quả.
-->
<div class="flash-message">
    @foreach (['danger', 'warning', 'success', 'info'] as $msg)
      @if(Session::has('alert-' . $msg))
      <p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }} <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a></p>
      @endif
    @endforeach
</div>

<!-- Tạo nút Thêm mới sản phẩm 
- Theo quy ước, các route đã được đăng ký trong file `web.php` đều phải được đặt tên để dễ dàng bảo trì code sau này.
- Đường dẫn URL là đường dẫn được tạo ra bằng route có tên `danhsachsanpham.create`
- Sẽ có dạng http://tenmiencuaban.com/admin/danhsachsanpham/create
-->
<a href="{{ route('danhsachsanpham.create') }}" class="btn btn-primary">Thêm mới sản phẩm</a>

<!-- Tạo table hiển thị danh sách các sản phẩm -->
<table class="table table-bordered">
    <thead>
        <tr>
            <th>Mã</th>
            <th>Tên</th>
            <th>Hình ảnh</th>
            <th>Thuộc loại</th>
            <th>Sửa-Xóa</th>
        </tr>
    </thead>
    <tbody>
        <!-- Sử dụng vòng lặp foreach để duyệt qua các sản phẩm 
        - Biến $danhsachsanpham là biến được truyền qua từ action `index()` trong controller SanPhamController.
        -->
        @foreach($danhsachsanpham as $sp)
            <tr>
                <td>{{ $sp->sp_ma }}</td>
                <td>{{ $sp->sp_ten }}</td>
                <td><img src="{{ asset('assets/storage/photos/' . $sp->sp_hinh) }}" class="img-list" /></td>
                <td>{{ $sp->loaisanpham->l_ten }}</td>
                <td>
                    <!-- Tạo nút Sửa sản phẩm 
                    - Theo quy ước, các route đã được đăng ký trong file `web.php` đều phải được đặt tên để dễ dàng bảo trì code sau này.
                    - Đường dẫn URL là đường dẫn được tạo ra bằng route có tên `danhsachsanpham.edit`
                    - Route `danhsachsanpham.edit` cần truyền vào 1 tham số {id}. Giá trị cần truyền là {id} của sản phẩm người dùng cần hiệu chỉnh.
                    - Các tham số cần truyền vào hàm route() là 1 array[]
                    - Sẽ có dạng http://tenmiencuaban.com/admin/danhsachsanpham/{id}/edit
                    -->
                    <a href="{{ route('danhsachsanpham.edit', ['id' => $sp->sp_ma]) }}" class="btn btn-primary pull-left">Sửa</a>

                    <!-- Tạo nút Xóa sản phẩm 
                    - Theo quy ước, các route đã được đăng ký trong file `web.php` đều phải được đặt tên để dễ dàng bảo trì code sau này.
                    - Đường dẫn URL là đường dẫn được tạo ra bằng route có tên `danhsachsanpham.destroy`
                    - Route `danhsachsanpham.destroy` cần truyền vào 1 tham số {id}. Giá trị cần truyền là {id} của sản phẩm người dùng cần xóa.
                    - Các tham số cần truyền vào hàm route() là 1 array[]
                    - Sẽ có dạng http://tenmiencuaban.com/admin/danhsachsanpham/{id}
                    -->
                    <form method="post" action="{{ route('danhsachsanpham.destroy', ['id' => $sp->sp_ma]) }}" class="pull-left">
                        <!-- Khi gởi Request Xóa dữ liệu, Laravel Framework mặc định chỉ chấp nhận thực thi nếu có gởi kèm field `_method=DELETE` -->
                        <input type="hidden" name="_method" value="DELETE" />
                        <!-- Khi gởi bất kỳ Request POST, Laravel Framework mặc định cần có token để chống lỗi bảo mật CSRF 
                        - Bạn có thể tắt đi, nhưng lời khuyên là không nên tắt chế độ bảo mật CSRF đi.
                        - Thay vào đó, sử dụng hàm `csrf_field()` để tự sinh ra 1 input có token dành riêng cho CSRF
                        -->
                        {{ csrf_field() }}
                        <button type="submit" class="btn btn-danger">Xóa</button>
                    </form>
                </td>
            </tr>
        @endforeach
    </tbody>
</table>
@endsection
Kiểm tra action index
Chạy câu lệnh php artisan serve, truy cập địa chỉ http://127.0.0.1:8000/admin/danhsachsanpham để kiểm tra kết quả.      

Các bài họ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


  1. Bức tranh Tổng thể về Lập trình WEB
  2. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế Backend 1
    1. Xây dựng chức năng CRUD Master Detail - Đơn hàng - Index