Quản trị table sản phẩm với Laravel

Quản trị table sản phẩm với Laravel hướng dẫn đầy đủ quản trị dữ liệu table sản phẩm với các thao tác xem danh sách, thêm, sửa, xóa sản phẩm.


Mục lục

Chuẩn bị quản trị table sản phẩm

1. Tạo resource controller

php artisan make:controller SanphamController --resource

File SanphamController.php sẽ được tạo và có sẵn các hàm như bên dưới

<?php
//app/Http/Controllers/SanphamController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SanphamController extends Controller {
    public function index() { }
    public function create() { }
    public function store(Request $request) {  }
    public function show($id) {  }
    public function edit($id) {  }
    public function update(Request $request, $id) { }
    public function destroy($id) { }
}

2. Tạo routing cho chức năng quản trị sản phẩm

Mở routes/web.php và code :

use App\Http\Controllers\SanphamController;
Route::resource('admin/sanpham', SanphamController::class);

3. Tạo model ORM Sanpham

Chúng ta sẽ tương tác với database qua Eloquent ORM. Cho nên cần tạo model Sanpham. Nếu bạn chưa tạo model thì thực hiện tạo với lệnh php artisan make:model Sanpham Và khai báo các thông số trong model như sau:

<?php //app/Models/Sanpham.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SanPham extends Model {
   use HasFactory;
   protected $table ="sanpham"; 
   public $primaryKey = "id";
   public $timestamps = true;  
   protected $fillable = ['id', 'tensp', 'giasp', 'solanxem', 'hot', 'mota', 'hinh', 'ngay', 'idLoai'];
   protected $dates = ['ngay'];
   protected $attributes= ['solanxem'=>0, 'hot'=>0, 'hinh'=>''];  
}

Danh sách sản phẩm

1. Nạp view trong controller

Code trong hàm index() của SanphamController

public function index() { 
  return view("admin/sanpham");
}

2. Tạo file views/admin/sanpham.blade.php

@extends('layoutadmin')
@section('noidung')
    <h1 class="text-primary p-2 h3" >QUẢN TRỊ SẢN PHẨM</h1>
    <!-- table sản phẩm -->
@endsection

Test:  http://localhost:8000/admin/sanpham

3. Lấy danh sách loại từ database

– Trong SanphamController (phía trên class) , chỉ định useBootsrap cho paginator.

use Illuminate\Pagination\Paginator;
Paginator::useBootstrap();

– Trong hàm index:  lấy 1 trang dữ liệu

public function index() { 
  $perPage = 3;
  $listsp=\App\Models\Sanpham::orderBy('ngay','desc')->paginate($perPage );
  return view("admin.sanpham", ['listsanpham'=>$listsp] );
}

4. Hiển thị dữ liệu

<table class='table table-hover table-strip table-bordered'>
    <tr class="bg-light">
    <th>id</th> <th>Tên sản phẩm</th> <th>Giá SP / Ngày</th><th>Xem / Hot</th>
    <th>Loại</th> <th class="text-end">Hành động</th>
    </tr>
    @foreach ($listsanpham as $row)
    <tr><td class="align-middle" width="120"> 
        <img src="{{$row->hinh}}" width="120" height="160"> 
        </td>
        <td class="align-middle" width="600"> 
            <b class="text-primary">{{$row->tensp}}</b> <br>
            {{$row->mota}}
        </td>
        <td class="align-middle text-center"> 
            Giá: <b>{{number_format($row->giasp,0,",",".")}} </b> <br>            
                {{ date('d/m/Y',strtotime($row->ngay))}} 
        </td>
        <td class="align-middle text-center"> 
            Xem: {{$row->solanxem}} <br> 
            Hot: {{($row->hot==1)? "Nổi bật":"Bình thường"}}
        </td>
        <td class="align-middle text-center">
            {{ App\Http\Controllers\SanphamController::tenLoai($row->idLoai)}}
        </td>
        <td class="align-middle text-end">               
            <form action="/admin/sanpham/{{$row->id}}" method="post">
            <a href="/admin/sanpham/{{$row->id}}/edit" class="btn btn-primary">
               Chỉnh
            </a>            
            <button class="btn btn-danger" type="submit">Xóa</button>
            @csrf  @method('DELETE')
            </form>
        </td>
    </tr>
    @endforeach
    <tr> <td colspan="4"> {{ $listsanpham->onEachSide(5)->links()}} </td> </tr>
</table>

Thêm sản phẩm

1. Tạo view – form thêm sản phẩm

<!-- views/admin/sanpham_them.php -->
@extends('layoutadmin')
@section('noidung')
<form class="mx-auto p-3 border border-primary" method="post" action="/admin/sanpham">
<h1 class="text-primary p-2 h3" >THÊM SẢN PHẨM</h1>
<div class="mb-3 row">
    <div class="col-md-6">
         <label>Tên sản phẩm</label> <input class="form-control" name="tensp" >
    </div>
    <div class="col-md-6">
         <label>Giá SP</label> <input class="form-control" name="giasp" type="number">
    </div>
</div>
<div class="mb-3 row">
    <div class="col-md-6">
         <label>Ngày</label> <input class="form-control" name="ngay" type="date">
    </div>
    <div class="col-md-6">
         <label>Hình</label> <input class="form-control" name="hinh" type="text">
    </div>
</div>
<div class="mb-3 row">
    <div class="col-md-6">
         <label>Loại</label> 
         <select class="form-control" name="idLoai">
             <?php $loaisp = \App\Models\Loaisp::all();?>
             @foreach ($loaisp as $loai )
             <option value="{{$loai->id}}"> {{$loai->tenLoai}}</option>
             @endforeach
        </select>
    </div>
    <div class="col-md-6">
         <label>Hot</label> 
         <div class="form-control">
            <input name="hot" type="radio" value="1"> Hot
            <input name="hot" type="radio" value="0" checked> Không hot
         </div>
    </div>
</div>
<div class="mb-3 row">
    <label>Mô tả</label> 
    <textarea name="mota" rows="5" class="form-control"></textarea>    
</div>
<div class="mb-3">
    <button type="submit" class="btn btn-warning py-2 px-5" >Lưu</button>
</div>  @csrf
</form> 
@endsection

2. Nạp view trong controller

Thực hiện trong hàm create() của controller Loaisp

public function create() { 
    return view("admin.sanpham_them");
}

Test xem form http://localhost:8000/admin/loaisp/create

3. Code lưu database

Viết trong hàm store của controller Loaisp

public function store(Request $request) {  
    $arr = $request->post();
    $tensp = ($request->has('tensp'))? $arr['tensp']:"";
    $giasp = ($request->has('giasp'))? (int) $arr['giasp']:0;
    $hinh = ($request->has('hinh'))? $arr['hinh']:"";
    $ngay = ($request->has('ngay'))? $arr['ngay']:"";
    $idLoai = ($request->has('idLoai'))? (int)$arr['idLoai']:"";
    $hot = ($request->has('hot'))? (int)$arr['hot']:0;
    $mota = ($request->has('mota'))? $arr['mota']:"";
    
    $tensp = trim(strip_tags($tensp));
    $hinh = trim(strip_tags($hinh));

    $sp = new \App\Models\Sanpham;
    $sp->tensp = $tensp;
    $sp->giasp = $giasp;
    $sp->hinh = $hinh;
    $sp->ngay = $ngay;
    $sp->hot= $hot;
    $sp->mota = $mota;
    $sp->idLoai = $idLoai;
    $sp->save();
    return redirect('/admin/sanpham');
}

Test

4. Validate form với request class

Chạy lệnh : php artisan make:request RuleNhapSanpham

Mở file app/Http/Requests/RuleNhapSanpham.php và

  • Hàm authorize(): dùng true để cho phép hoạt động
  • Khai báo các rule trong hàm rules() . Tham khảo https://laravel.com/docs/9.x/validation
  • Định nghĩa hàm messages() để khai báo các báo lỗi
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RuleNhapSanpham extends FormRequest {
    public function authorize() { return true;}
    public function rules() {
        return [
            'tensp' => ['string','required','min:2','max:100'],
            'giasp' => ['numeric','required','integer', 'min:0'],
            'ngay' => ['date'],
            'hinh' => ['string'],
        ];
    }
    public function messages(){ return [
        'tensp.string' => 'Nhập tên sản phẩm là chuỗi ',
        'tensp.required' => 'Bạn chưa nhập tên sản phẩm',
        'tensp.min' => 'Tên sản phẩm ngắn quá vậy',
        'tensp.max' => 'Tên sản phẩm dài quá',
        'giasp.required' => 'Bạn chưa nhập giá sản phẩm',
        'giasp.min' => 'Nhập giá>=0 nhé',
        'ngay.date' =>'Nhập đúng dạng ngày nha bồ',
        'hinh.string' =>'Nhập hình là chuỗi.'
      ];
    }
}

– Hiện các lỗi trong view: Mở views/admin/loaisp_them.blade.php, code trong tag form

@if ($errors->any())
<div class="alert alert-info p-2">
  <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach  </ul>
</div>
@endif

– Code sử dụng RuleNhapSanpham trong controller: Sử dụng trong hàm stored()

– Hiện các giá trị cũ user đã nhập trong form: Sử dụng hàm old() trong value của các input

Test Vào http://localhost:8000/admin/sanpham/create  , không nhập gì cả nhắp nút Lưu sẽ báo rất nhiều lỗi như hình dưới

Có nhập vào đúng thì sẽ lư vào db

Sửa sản phẩm

1. Tạo view – form chỉnh sản phẩm

Save file views/admin/sanpham_them.blade.php  thành views/admin/sanpham_edit.blade.php

2. Chỉnh các thông số trong form

– Chỉnh giá trị thuộc tính action của form để được như sau:

– Thêm {{ method_field(‘PUT’) }} vào trong tag form để được như sau

3. Sửa giá trị value trong các tag để được như sau

4. Nạp view trong controller

Thực hiện trong hàm edit () của controller Loaisp

public function edit($id) {  
    $sp = \App\Models\Sanpham::find($id);
    if ($sp==null) {
        $request->session()->flash('thongbao', "Sản phẩm $id không có");
        return redirect("/thongbao");
    }
    return view("admin.sanpham_edit", ['sp'=>$sp] );
}

Test xem form http://localhost:8000/admin/sanpham/1/edit

5. Code lưu database

Viết trong hàm update() của SanphamController

public function update(RuleNhapSanPham $request, $id) { 
    $arr = $request->post();
    $tensp = ($request->has('tensp'))? $arr['tensp']:"";
    $giasp = ($request->has('giasp'))? (int) $arr['giasp']:0;
    $hinh = ($request->has('hinh'))? $arr['hinh']:"";
    $ngay = ($request->has('ngay'))? $arr['ngay']:"";
    $idLoai = ($request->has('idLoai'))? (int)$arr['idLoai']:"";
    $hot = ($request->has('hot'))? (int)$arr['hot']:0;
    $mota = ($request->has('mota'))? $arr['mota']:"";
    
    $tensp = trim(strip_tags($tensp));
    $hinh = trim(strip_tags($hinh));
    
    $sp = \App\Models\Sanpham::find($id);
    if ($sp==null) {
        $request->session()->flash('thongbao', "Sản phẩm $id không tồn tại");
        redirect("/thongbao");
    }
    $sp->tensp = $tensp;
    $sp->giasp = $giasp;
    $sp->hinh = $hinh;
    $sp->ngay = $ngay;
    $sp->hot= $hot;
    $sp->mota = $mota;
    $sp->idLoai = $idLoai;
    $sp->save();
    return redirect('/admin/sanpham');
}

Test

Xóa sản phẩm

1. Hỏi trước khi xóa

Mở file sanpham.blade.php và thêm code vào nút Xóa:

<!-- views/sanpham.blade.php -->
<button onclick="return confirm('Xóa hả?')" class="btn btn-danger" type="submit"> Xóa </button>

2. Code xóa sản phẩm trong controller

Code trong hàm destroy của SanphamController

public function destroy($id) {  
    $sp = \App\Models\Sanpham::find($id);
    if ($sp==null) {
        $request->session()->flash('thongbao', "Sản phẩm $id không tồn tại");
        redirect("/thongbao");
    }
    $sp->delete();
    return redirect('/admin/sanpham');
}

Test

Sử dụng WebEditor

Trong chức năng thêm sản phẩm, sẽ tốt hơn nếu như mục mô tả được biến thành vùng soạn thảo như word. Xem hình sau để rồi thực hiện nhé

Có nhiều thư viên giúp biến 1 textarea trong form thành edior rất hay như InnovaEdidor, TinyMCE, CKEditor. Bây giở là phần hướng dẫn bạn thực hiện với CKEditor 4

  • Mở file sanpham_them.blade.php rồi khai báo id cho textarea là mota
  • Tiếp theo chèn script: <script src=”https://cdn.ckeditor.com/4.20.2/full/ckeditor.js”> </script>
  • Nhập cấu hình gắn CKEditor vào textarea mota, chỉ định độ cao, độ rộng, ngôn ngữ vi như hình dưới. Xong rồi đó, thưởng thức kết quả thôi.

Bạn thực hiện tương tự như với file sanpham_sua.blade.php


Đến đây, bài viết quản trị table sản phẩm với Laravel đã hướng dẫn bạn thực hiện chức năng hiện danh sách sản phẩm, thêm sản phẩm, sửa sản phẩm, xóa sản phẩm. Đây là phần việc bạn sẽ phải làm khi thực hiện các website thương mại. Tút thêm giao diện và các chức năng li ti cho mút nhé.