Xây dựng trang quản trị laravel 9 với Laravel-admin bằng demo 1 trang blog cá nhân phần 3 Grid
Sau đây chúng ta sẽ bắt đầu tìm hiểu dần phần Admin Controller trong laravel-admin .Đầu tiên là Grid hiển thị phần index trong CRUD :
protected function grid()
{
$grid = new Grid(new Category());
$grid->filter(function (Grid\Filter $filter){
$filter->disableIdFilter();
$filter->like('title');
});
$grid->paginate(10);
$grid->column('id', __('Id'));
$grid->column('title', __('Tiêu đề'))->filter()->limit(50);
$grid->column('slug', __('Đường dẫn'));
$grid->column('parent_id', __('Dah mục cha'))->display(function ($parent_id){
$name = Category::find($parent_id);
if($name)
{
return $name->title;
}else{
return 'ROOT';
}
});
$grid->column('total','Tổng số bài viết')->display(function (){
$total = DB::table('posts')->where('category_id','=',$this->id)->count();
if($total){
return $total. ' bài viết';
}else{
return 'Chưa có bài viết';
}
});
return $grid;
}
1.Cách sử dụng cơ bản
Thêm cột để hiển thị dữ liệu:
// Thêm trực tiếp 1 cột thông qua tên trường
$grid->username('Username');
// Hiệu ứng tương tự như trên
$grid->column('username', 'Username');
// Hiển thị dữ liệu dạng Json
$grid->column('profile->mobile', '手机号');
// Hiển thị nhiều cột
$grid->columns('email', 'username' ...);
Chúng ta có thể lấy dữ liệu theo điều kiện bằng cách sử dụng query:
$grid->model()->where('id', '>', 100)
->whereIn('id', [1, 2, 3])
->whereBetween('votes', [1, 100])
->whereColumn('updated_at', '>', 'created_at')
->orderBy('id', 'desc')
->take(100)
Tùy chỉnh kết quả hiển thị của cột
$grid->text()->display(function($text) {
return str_limit($text, 30, '...');
});
$grid->name()->display(function ($name) {
return "$name";
});
$grid->email()->display(function ($email) {
return "mailto:$email";
});
// Hiển thị một cột không được định nghĩa trong bảng dữ liệu
// Có thể sử dụng dữ liệu của cột khác để hiển thị
$grid->column('full_name')->display(function () {
return $this->first_name . ' ' . $this->last_name;
});
Ta có thể tắt một số tính năng mặc định
$grid->disableCreateButton();
$grid->disablePagination();
$grid->disableFilter();
$grid->disableExport();
$grid->disableRowSelector();
$grid->disableActions();
$grid->disableColumnSelector();
2. Hiển thị dữ liệu có quan hệ - Relation
Để có thể hiển thị dữ liệu có quan hệ thì chúng ta phải định nghĩa các mối quan hệ trong Model sau đó mới sử dụng được ở grid()
1. One to One - Quan hệ 1-1
Ví dụ model User
và Profile
có quan hệ 1-1
$grid = new Grid(new User);
$grid->column('id', 'ID')->sortable();
$grid->column('name', 'Name');
$grid->column('profile.age');
$grid->column('profile.gender');
//or
$grid->profile()->age();
$grid->profile()->gender();
return $grid;
2. One to Many - Quan hệ 1-n
Ví dụ một Post
có nhiều Comment
. Hiển thị bảng dữ liệu Post
như sau
$grid = new Grid(new Post);
$grid->column('id', 'id')->sortable();
$grid->column('title');
$grid->column('content');
$grid->column('comments', 'Comments count')->display(function ($comments) {
$count = count($comments);
return "{$count}";
});
return $grid;
Còn nếu chúng ta muốn hiển thị bảng dữ liệu của Comment
:
$grid = new Grid(new Comment);
$grid->column('id');
$grid->column('post.title');
$grid->column('content');
return $grid;
3. Many to Many - Quan hệ n-n
Ví dụ model User
và Role
có quan hệ nhiều - nhiều.
$grid = new Grid(new User);
// Sử dụng sortable() để dữ liệu có thể sắp xếp theo cột.
$grid->id('ID')->sortable();
$grid->username();
$grid->name();
$grid->roles()->display(function ($roles) {
$roles = array_map(function ($role) {
return "{$role['name']}";
}, $roles);
return join(' ', $roles);
});
return $grid;
3. Filters
Laravel-admin cung cấp bộ lọc filter tiện dụng và dễ dàng tùy chỉnh theo nhu cầu.
$grid->filter(function ($filter) {
// Xóa ID filter mặc định
$filter->disableIdFilter();
// Thêm 1 filter theo cột dữ liệu
$filter->like('name', 'Name');
$filter->like('email', 'Email');
});
1. Filter type
Laravel-admin xây dựng các loại filter tương tự như Query Builder:
// WHERE 'column' = $input
$filter->equal('column', $label);
$filter->notEqual('column', $label);
// WHERE 'column' LIKE "%"$input"%"
$filter->like('column', $label);
$filter->contains('title');
// WHERE 'column' ILIKE "%"$input"%"
$filter->ilike('column', $label);
// WHERE 'column' LIKE $input"%"
$filter->startsWith('title');
// WHERE 'column' LIKE "%"$input
$filter->endsWith('title');
// WHERE 'column' > $input
$filter->gt('column', $label);
// WHERE 'column' < $input
$filter->lt('column', $label);
// WHERE 'column' BETWEEN "$start" AND "$end":
$filter->between('column', $label);
// set datetime field type
$filter->between('column', $label)->datetime();
// set time field type
$filter->between('column', $label)->time();
// WHERE 'column' IN (...$inputs)
$filter->in('column', $label)->multipleSelect(['key' => 'value']);
// WHERE 'column' NOT IN (...$inputs)
$filter->notIn('column', $label)->multipleSelect(['key' => 'value']);
// WHERE DATE(column) = $input
$filter->date('column', $label);
$filter->day('column', $label);
$filter->month('column', $label);
$filter->year('column', $label);
// Tạo truy vấn phức tạp
// WHERE title LIKE "%$input%" OR content LIKE "%$input%"
$filter->where(function ($query) {
$query->where('title', 'like', "%{$this->input}%")
->orWhere('content', 'like', "%{$this->input}%");
}, 'Text');
// Truy vấn với relationship
$filter->where(function ($query) {
$query->whereHas('profile', function ($query) {
$query->where('address', 'like', "%{$this->input}%")->orWhere('email', 'like', "%{$this->input}%");
});
}, 'Address or mobile');
2. Truy vấn xác định (Define the scope of the query)
Chúng ta có thể nhóm các câu truy vấn dữ liệu thường xuyên sử dụng dưới dạng query scope và nó sẽ được hiển thị dưới dạng drop-down menu ở filter
$filter->scope('male', 'Male')->where('gender', 'm');
$filter->scope('new', 'Recently modified')
->whereDate('created_at', date('Y-m-d'))
->orWhere('updated_at', date('Y-m-d'));
// Relationship query
$filter->scope('address')->whereHas('profile', function ($query) {
$query->whereNotNull('address');
});
$filter->scope('trashed', 'Soft deleted data')->onlyTrashed();
Param đầu tiên của scope
là khóa của truy vấn. Nó sẽ xuất hiện trong param url. Param thứ hai là label của item drop-down menu. Nếu không được điền, param sẽ được hiển thị dưới dạng nhãn.
3. Field type
Loại input mặc định là text và chúng ta có thể thay đổi type của input:
$filter->equal('column')->url();
$filter->equal('column')->email();
$filter->equal('column')->integer();
$filter->equal('column')->ip();
$filter->equal('column')->mac();
$filter->equal('column')->mobile();
// $options refer to https://github.com/RobinHerbots/Inputmask/blob/4.x/README_numeric.md
$filter->equal('column')->decimal($options = []);
// $options refer to https://github.com/RobinHerbots/Inputmask/blob/4.x/README_numeric.md
$filter->equal('column')->currency($options = []);
// $options refer to https://github.com/RobinHerbots/Inputmask/blob/4.x/README_numeric.md
$filter->equal('column')->percentage($options = []);
// $options refer to https://github.com/RobinHerbots/Inputmask
$filter->equal('column')->inputmask($options = [], $icon = 'pencil');
// Select
$filter->equal('column')->select(['key' => 'value'...]);
// Hoặc select dữ liệu từ API
$filter->equal('column')->select('api/users');
// MultipleSelect - Tương đương với truy vấn IN, NOT IN
$filter->in('column')->multipleSelect(['key' => 'value'...]);
$filter->in('column')->multipleSelect('api/users');
// Radio
$filter->equal('released')->radio([
'' => 'All',
0 => 'Unreleased',
1 => 'Released',
]);
// Checkbox
$filter->in('gender')->checkbox([
'm' => 'Male',
'f' => 'Female',
]);
// Input kết hợp bootstrap-datetimepicker
$filter->equal('column')->datetime($options);
// `date()` equals to `datetime(['format' => 'YYYY-MM-DD'])`
$filter->equal('column')->date();
// `time()` equals to `datetime(['format' => 'HH:mm:ss'])`
$filter->equal('column')->time();
// `day()` equals to `datetime(['format' => 'DD'])`
$filter->equal('column')->day();
// `month()` equals to `datetime(['format' => 'MM'])`
$filter->equal('column')->month();
// `year()` equals to `datetime(['format' => 'YYYY'])`
$filter->equal('column')->year();
4. Inline Editing
Chúng ta có thể sửa dữ liệu trực tiếp trong bằng bằng cách click vào dữ liệu, một pop-up dialog box sẽ hiện ra và chỉ việc save thôi.
Lưu ý: Đối với cột có thể sửa trực tiếp thì nó phải là cột tương ứng tồn tại trong model form.
// Text input
$grid->column('title')->editable();
// Textarea input
$grid->column('title')->editable('textarea');
// Select
$grid->column('title')->editable('select', [1 => 'option1', 2 => 'option2', 3 => 'option3']);
// Date selection
$grid->column('birth')->editable('date');
$grid->column('published_at')->editable('datetime');
$grid->column('year')->editable('year');
$grid->column('month')->editable('month');
$grid->column('day')->editable('day');
// Switch
// set text, color, and stored values
$states = [
'on' => ['value' => 1, 'text' => 'open', 'color' => 'primary'],
'off' => ['value' => 2, 'text' => 'close', 'color' => 'default'],
];
$grid->column('status')->switch($states);
//Switch group
$states = [
'on' => ['text' => 'YES'],
'off' => ['text' => 'NO'],
];
$grid->column('switch_group')->switchGroup([
'hot' => 'hot',
'new' => 'latest'
'recommend' => 'recommended',
], $states);
// Radio
$grid->column('options')->radio([
1 => 'Sed ut perspiciatis unde omni',
2 => 'voluptatem accusantium doloremque',
3 => 'dicta sunt explicabo',
4 => 'laudantium, totam rem aperiam',
]);
//Checkbox
$grid->column('options')->checkbox([
1 => 'Sed ut perspiciatis unde omni',
2 => 'voluptatem accusantium doloremque',
3 => 'dicta sunt explicabo',
4 => 'laudantium, totam rem aperiam',
]);