我们知道,做后台管理系统需要很多表格用来展示我们的数据,笔者在tp项目中使用过datatables,对于快速开发来说,datatables将是一个不错的选择。
首先来看一下最终的效果:
准备工作:
1、首先,确保你的laravel配置正确(站点能够正常访问、数据库连接正常...)
2、下载Datatables资源文件(AdminLTE中包含了Datatables资源文件,读者使用其他模板需另行引入的请自行百度),并在页面中引入,确保资源文件能够正确加载。
3、文档:Laravel Datatables开发文档
系统要求:
Laravel 5.5+
jQuery DataTables v1.10.x
ok,开始动手!(以administrator页面为例)
1、安装composer包
composer require yajra/laravel-datatables-oracle:^8.0
如果你需要使用datatables的全部插件可使用以下命令安装
composer require yajra/laravel-datatables:^1.0
2、配置Datatables(此步骤可省,但还是配置下,确保后续不会出错)
安装完成之后,打开config/app.php
,键入如下代码
'providers' => [
// ...
Yajra\DataTables\DataTablesServiceProvider::class,
],
使用命令发布配置和资源文件
php artisan vendor:publish --tag=datatables
3、创建administrator模型
php artisan make:model Models/Administrator -m
编辑数据库迁移文件
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAdministratorsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('administrators', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('login_name')->unique();
$table->string('display_name');
$table->string('password');
$table->string('avatar')->nullable();
$table->rememberToken();
$table->tinyInteger('status')->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('administrators');
}
}
4、创建AdministratorDatatable
php artisan datatables:make Administrator
此命令会生成DataTables/AdministratorDatatable.php
,打开并编辑:
<?php
namespace App\DataTables;
use App\Models\Administrator;
use Yajra\DataTables\Services\DataTable;
class AdministratorDataTable extends DataTable
{
/**
* Build DataTable class.
*
* @param mixed $query Results from query() method.
* @return \Yajra\DataTables\DataTableAbstract
*/
public function dataTable($query)
{
return datatables($query)
->setRowClass('text-center')
->editColumn('avatar', function (Administrator $administrator) {
return '<img class="img" width="24" height="24" src="'.$administrator->avatar.'">';
})
->editColumn('roles', function (Administrator $administrator) {
return $administrator->roles->map(function ($role) {
return '<span class="label label-info margin-r-5">'.$role->identifier.'['.$role->name.']'.'</span>';
})->implode('');
})
->editColumn('status', function (Administrator $administrator) {
if ($administrator->status == 1) {
return '<span class="label label-primary">正常</span>';
}
return '<span class="label label-warning">禁用</span>';
})
->rawColumns(['avatar', 'status', 'roles', 'action'])
->addColumn('action', function (Administrator $administrator) {
$edit_path = admin_base_path('auth/administrators/'.$administrator->id.'/edit');
$delete_path = admin_base_path('auth/administrators/'.$administrator->id);
return '<a href="'.$edit_path.'" class="btn btn-xs btn-primary margin-r-5">'.
'<i class="fa fa-edit"></i> 编辑</a>'.
'<a class="btn btn-xs btn-danger margin-r-5 row-delete" data-url="'.$delete_path.'">'.
'<i class="fa fa-trash"></i> 删除</a>';
});
}
/**
* Get query source of dataTable.
*
* @param \App\Models\Administrator $model
* @return \Illuminate\Database\Eloquent\Builder
*/
public function query(Administrator $model)
{
return $model->newQuery()->select('id', 'login_name', 'display_name',
'avatar', 'status', 'created_at', 'updated_at');
}
/**
* Optional method if you want to use html builder.
*
* @return \Yajra\DataTables\Html\Builder
*/
public function html()
{
return $this->builder()
->addTableClass('table-bordered table-striped')
->columns($this->getColumns())
->minifiedAjax('administrators')
->addAction(['title' => '操作', 'class' => 'text-center'])
->parameters([
'dom' => 'Bfrtip',
'buttons' => [
['extend' => 'create', 'text' => '<i class="fa fa-plus"> 创建</i>'],
['extend' => 'excel', 'text' => '<i class="fa fa-file-excel-o"> 导出</i>'],
['extend' => 'print', 'text' => '<i class="fa fa-print"> 打印</i>'],
['extend' => 'reload', 'text' => '<i class="fa fa-refresh"> 刷新'],
],
]);
}
/**
* 获取数据列
*
* @return array
*/
protected function getColumns()
{
return [
['name' => 'id', 'data' => 'id', 'title' => 'ID', 'class' => 'text-center'],
['name' => 'login_name', 'data' => 'login_name', 'title' => '登录名', 'class' => 'text-center', 'orderable' => false],
['name' => 'display_name', 'data' => 'display_name', 'title' => '显示名', 'class' => 'text-center', 'orderable' => false],
['name' => 'avatar', 'data' => 'avatar', 'title' => '头像', 'class' => 'text-center', 'orderable' => false],
['name' => 'status', 'data' => 'status', 'title' => '状态', 'class' => 'text-center'],
['name' => 'roles', 'data' => 'roles', 'title' => '角色', 'class' => 'text-center', 'orderable' => false],
['name' => 'created_at', 'data' => 'created_at', 'title' => '创建时间', 'class' => 'text-center'],
['name' => 'updated_at', 'data' => 'updated_at', 'title' => '更新时间', 'class' => 'text-center'],
];
}
/**
* 设置导出文件名
*
* @return string
*/
protected function filename()
{
return 'Administrator_' . date('YmdHis');
}
/**
* 打印列
* @var array
*/
protected $printColumns = ['id', 'login_name', 'display_name', 'created_at', 'updated_at'];
}
5、创建视图文件resource/views/admin/auth/administrator/index.blade.php
(视图文件使用布局,读者可参考之前的文章或参考源码)
@extends('admin::layouts.layout')
@section('content')
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
管理员
<small>列表</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-home"></i> administrators</a></li>
<li class="active"> index</li>
</ol>
</section>
<!-- Main content -->
<section class="content container-fluid">
<div class="row">
<div class="col-sm-12">
<div class="box box-widget">
<div class="box-body table-block">
{!! $dataTable->table() !!}
</div>
</div>
</div>
</div>
</section>
<!-- /.content -->
{!! $dataTable->scripts() !!}
@endsection
创建视图文件resource/views/admin/auth/administrator/create.blade.php
@extends('admin::layouts.layout')
@section('content')
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
管理员
<small>创建</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-home"></i> administrators</a></li>
<li class="active"> create</li>
</ol>
</section>
<!-- Main content -->
<section class="content container-fluid">
<div class="row">
<div class="col-sm-12">
<div class="box box-widget">
<div class="box-header with-border">
<a href="{{ admin_base_path('auth/administrators') }}" class="btn btn-default">
<i class="fa fa-arrow-left"></i> 返回
</a>
</div>
<form class="form-horizontal" pjax-container action="{{ admin_base_path('auth/administrators') }}" method="post">
@csrf
<div class="box-body">
<div class="fields-group">
<div class="form-group {{ $errors->has('login_name') ? ' has-error' : '' }}">
<label for="login_name" class="col-sm-3 control-label">登 录 名:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="login_name" name="login_name" value="{{ old('login_name') }}" placeholder="登 录 名">
</div>
@if ($errors->has('login_name'))
<div class="col-sm-offset-3 col-sm-8">
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first('login_name') }}</strong>
</span>
</div>
@endif
</div>
</div>
<div class="fields-group">
<div class="form-group {{ $errors->has('display_name') ? ' has-error' : '' }}">
<label for="display_name" class="col-sm-3 control-label">显 示 名:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="display_name" name="display_name" value="{{ old('display_name') }}" placeholder="显 示 名">
</div>
@if ($errors->has('display_name'))
<div class="col-sm-offset-3 col-sm-8">
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first('display_name') }}</strong>
</span>
</div>
@endif
</div>
</div>
<div class="form-group {{ $errors->has('roles') ? ' has-error' : '' }}">
<label for="method" class="col-sm-3 control-label">角 色:</label>
<div class="col-sm-8">
<select class="form-control select2" style="width: 100%;" name="roles[]" multiple>
@foreach ($roleList as $role)
<option value="{{ $role->id }}">
{{ $role->identifier.' ['.$role->name.']' }}
</option>
@endforeach
</select>
</div>
@if ($errors->has('roles'))
<div class="col-sm-offset-3 col-sm-8">
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first('permissions') }}</strong>
</span>
</div>
@endif
</div>
{{--<div class="fields-group">--}}
{{--<div class="form-group">--}}
{{--<label for="avatar" class="col-sm-3 control-label">头 像:</label>--}}
{{--<div class="col-sm-8">--}}
{{--<input type="text" class="form-control" id="avatar" name="avatar" placeholder="选 择 头 像">--}}
{{--</div>--}}
{{--</div>--}}
{{--</div>--}}
<div class="fields-group">
<div class="form-group {{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-sm-3 control-label">密 码:</label>
<div class="col-sm-8">
<input type="password" class="form-control" id="password" name="password" placeholder="登 录 密 码">
</div>
@if ($errors->has('password'))
<div class="col-sm-offset-3 col-sm-8">
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first('password') }}</strong>
</span>
</div>
@endif
</div>
</div>
<div class="fields-group">
<div class="form-group {{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<label for="password_confirmation" class="col-sm-3 control-label">确 认 密 码:</label>
<div class="col-sm-8">
<input type="password" class="form-control" id="password_confirmation" name="password_confirmation" placeholder="确 认 密 码">
</div>
@if ($errors->has('password_confirmation'))
<div class="col-sm-offset-3 col-sm-8">
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first('password_confirmation') }}</strong>
</span>
</div>
@endif
</div>
</div>
</div>
<div class="box-footer">
<div class="col-sm-offset-3 col-sm-8">
<button type="reset" class="btn btn-warning pull-left">
<i class="fa fa-rotate-left"></i> 撤 销
</button>
<button type="submit" class="btn btn-primary pull-right">
<i class="fa fa-save"></i> 提 交
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<!-- /.content -->
<script>
$('.select2').select2()
</script>
@endsection
创建视图文件resource/views/admin/auth/administrator/edit.blade.php
@extends('admin::layouts.layout')
@section('content')
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
管理员
<small>编辑</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-home"></i> administrators</a></li>
<li class="active"> edit</li>
</ol>
</section>
<!-- Main content -->
<section class="content container-fluid">
<div class="row">
<div class="col-sm-12">
<div class="box box-widget">
<div class="box-header with-border">
<a href="{{ admin_base_path('auth/administrators') }}" class="btn btn-default">
<i class="fa fa-arrow-left"></i> 返回
</a>
</div>
<form class="form-horizontal" action="{{ admin_base_path('auth/administrators').'/'.$administrator->id }}" method="post">
@method('PATCH')
@csrf
<div class="box-body">
<div class="fields-group">
<div class="form-group {{ $errors->has('login_name') ? ' has-error' : '' }}">
<label for="login_name" class="col-sm-3 control-label">登 录 名:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="login_name" name="login_name" placeholder="登 录 名" value="{{ $administrator->login_name }}">
</div>
</div>
</div>
<div class="fields-group">
<div class="form-group {{ $errors->has('display_name') ? ' has-error' : '' }}">
<label for="display_name" class="col-sm-3 control-label">显 示 名:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="display_name" name="display_name" placeholder="显 示 名" value="{{ $administrator->display_name }}">
</div>
</div>
</div>
<div class="form-group {{ $errors->has('roles') ? ' has-error' : '' }}">
<label for="method" class="col-sm-3 control-label">角 色:</label>
<div class="col-sm-8">
<select class="form-control select2" style="width: 100%;" name="roles[]" multiple>
@foreach ($roleList as $role)
<option @foreach($administrator->roles as $a_role)
@if($role->id == $a_role->id)
{{ 'selected' }}
@endif
@endforeach value="{{ $role->id }}">
{{ $role->identifier.' ['.$role->name.']' }}
</option>
@endforeach
</select>
</div>
@if ($errors->has('roles'))
<div class="col-sm-offset-3 col-sm-8">
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first('permissions') }}</strong>
</span>
</div>
@endif
</div>
{{--<div class="fields-group">--}}
{{--<div class="form-group">--}}
{{--<label for="avatar" class="col-sm-3 control-label">头 像:</label>--}}
{{--<div class="col-sm-8">--}}
{{--<input type="text" class="form-control" id="avatar" name="avatar" placeholder="选 择 头 像">--}}
{{--</div>--}}
{{--</div>--}}
{{--</div>--}}
</div>
<div class="box-footer">
<div class="col-sm-offset-3 col-sm-8">
<button type="reset" class="btn btn-warning pull-left">
<i class="fa fa-rotate-left"></i> 撤 销
</button>
<button type="submit" class="btn btn-primary pull-right">
<i class="fa fa-save"></i> 提 交
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<!-- /.content -->
<script>
$('.select2').select2();
</script>
@endsection
6、创建administrator控制器
php artisan make:controller Admin/Auth/AdministratorController --resource
打开Admin/Auth/AdministratorController.php
并编辑
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\DataTables\AdministratorDataTable;
use App\Http\Controllers\Admin\BaseController;
use App\Models\Administrator;
use App\Models\Role;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class AdministratorController extends BaseController
{
/**
* 列表页
* @param AdministratorDataTable $dataTable
* @return mixed
*/
public function index(AdministratorDataTable $dataTable)
{
return $dataTable->render(admin_view_path('auth.administrator.index'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$roles = Role::all();
return view(admin_view_path('auth.administrator.create'))->with([
'roleList' => $roles,
]);
}
/**
*
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws \Exception
*/
public function store(Request $request)
{
$this->validate($request, [
'login_name' => 'required|unique:administrators',
'display_name' => 'required',
'roles' => 'required',
'password' => 'required|min:6|confirmed',
'password_confirmation' => 'required|min:6',
],[
'login_name.required' => '请输入登录名',
'login_name.unique' => '该登录名已存在',
'display_name.required' => '请输入显示名',
'roles.required' => '请选择一个或多个角色',
'password.required' => '请输入密码',
'password.min' => '密码至少6位',
'password.confirmed' => '两次输入密码不一致',
'password_confirmation.required' => '请输入确认密码',
'password_confirmation.min' => '密码至少6位',
]);
$administrator = new Administrator();
$administrator->login_name = $request->get('login_name');
$administrator->display_name = $request->get('display_name');
$administrator->password = Hash::make($request->get('password'));
$roles = $request->get('roles');
DB::beginTransaction();
try {
if (!$administrator->save()) {
throw new \Exception('保存失败');
}
if (!$administrator->updateRelation($roles)) {
throw new \Exception('保存失败');
}
DB::commit();
admin_toastr('角色更新成功!');
return redirect(admin_base_path('auth/administrator'));
} catch (\Exception $e) {
$error = $e->getMessage();
DB::rollBack();
admin_toastr($error, 'error');
return redirect()->back()->withInput()->withErrors([
'error' => $error
]);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$administrator = Administrator::find($id);
$roles = Role::all();
return view(admin_base_path('auth.administrator.edit'))->with([
'roleList' => $roles,
'administrator' => $administrator
]);
}
/**
* @param Request $request
* @param $id
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws \Exception
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'login_name' => 'required|unique:administrators',
'display_name' => 'required',
'roles' => 'required',
],[
'login_name.required' => '请输入登录名',
'login_name.unique' => '该登录名已存在',
'display_name.required' => '请输入显示名',
'roles.required' => '请选择一个或多个角色',
]);
$administrator = Administrator::find($id);
$administrator->login_name = $request->get('login_name');
$administrator->display_name = $request->get('display_name');
$roles = $request->get('roles');
DB::beginTransaction();
try {
if (!$administrator->save()) {
throw new \Exception('保存失败');
}
if (!$administrator->updateRelation($roles)) {
throw new \Exception('保存失败');
}
DB::commit();
admin_toastr('角色更新成功!');
return redirect(admin_base_path('auth/administrator'));
} catch (\Exception $e) {
$error = $e->getMessage();
DB::rollBack();
admin_toastr($error, 'error');
return redirect()->back()->withInput()->withErrors([
'error' => $error
]);
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
if (Administrator::find($id)->delete()) {
return response()->json([
'status' => true,
'message' => '删除成功!',
]);
} else {
return response()->json([
'status' => false,
'message' => '删除失败,请重试!',
]);
}
}
}
别忘了配置路由:
<?php
/**
* 后台路由
* Created by PhpStorm.
* User: chen
* Date: 18-4-6
* Time: 下午11:28
*/
use Illuminate\Routing\Router;
Route::group([
'prefix' => config('admin.route.prefix'),
'namespace' => config('admin.route.namespace'),
'middleware' => config('admin.route.middleware'),
], function (Router $router) {
//后台控制面板
$router->get('/', 'Home\HomeController@index')->name('home.index');
//登录页面
$router->get('login', 'Auth\LoginController@getLogin')->name('login.getLogin');
//登录
$router->post('login', 'Auth\LoginController@postLogin')->name('login.postLogin');
//注销登录
$router->post('logout', 'Auth\LoginController@postLogout')->name('login.logout');
/**
* auth模块
*/
//后台用户管理
$router->resource('auth/administrators', 'Auth\AdministratorController');
//权限管理
$router->resource('auth/permissions', 'Auth\PermissionController');
//权限策略管理
$router->resource('auth/policies', 'Auth\PolicyController');
//角色管理
$router->resource('auth/roles', 'Auth\RoleController');
//菜单管理
$router->resource('auth/menus', 'Auth\MenuController');
/**
* blog模块
*/
//文章管理
$router->resource('blog/articles', 'Blog\ArticleController');
});
7、本地化:创建一个单独文件,如datatable-language.js
并在页面中引入
$.fn.dataTable.defaults.oLanguage = {
"sProcessing": "处理中...",
"sLengthMenu": "显示 _MENU_ 项结果",
"sZeroRecords": "没有匹配结果",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sInfoPostFix": "",
"sSearch": "搜索:",
"sUrl": "",
"sEmptyTable": "表中数据为空",
"sLoadingRecords": "载入中...",
"sInfoThousands": ",",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "上页",
"sNext": "下页",
"sLast": "末页"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
};
$.fn.dataTable.defaults.autoWidth = false;
写在最后:表格中一些按钮事件请读者根据需要自行编码,这里只给出一个例子:删除按钮事件(引入了sweetalert插件以及toastr插件,如有需要请参考源码)
//datatables删除按钮
$('#pjax-container').on('click', '.row-delete', function () {
var del_url = $(this).data('url');
swal({
title: "确定删除此项?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "确 定",
closeOnConfirm: false,
cancelButtonText: "取 消"
}, function(){
$.ajax({
method: 'post',
url: del_url,
data: {
_method:'delete',
_token:csrf_token,
},
success: function (data) {
if (typeof data === 'object') {
if (data.status) {
swal(data.message, '', 'success');
$.pjax.reload('#pjax-container');
} else {
swal(data.message, '', 'error');
}
}
}
});
});
});
ok,大功告成,enjoy it !
下载:项目源码
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。