咱们知道,作后台管理系统须要不少表格用来展现咱们的数据,笔者在tp项目中使用过datatables,对于快速开发来讲,datatables将是一个不错的选择。
首先来看一下最终的效果:php
准备工做:
一、首先,确保你的laravel配置正确(站点可以正常访问、数据库链接正常...)
二、下载Datatables资源文件(AdminLTE中包含了Datatables资源文件,读者使用其余模板需另行引入的请自行百度),并在页面中引入,确保资源文件可以正确加载。
三、文档:Laravel Datatables开发文档html
系统要求:
Laravel 5.5+
jQuery DataTables v1.10.xlaravel
ok,开始动手!(以administrator页面为例)
一、安装composer包git
composer require yajra/laravel-datatables-oracle:^8.0
若是你须要使用datatables的所有插件可以使用如下命令安装github
composer require yajra/laravel-datatables:^1.0
二、配置Datatables(此步骤可省,但仍是配置下,确保后续不会出错)
安装完成以后,打开config/app.php
,键入以下代码ajax
'providers' => [ // ... Yajra\DataTables\DataTablesServiceProvider::class, ],
使用命令发布配置和资源文件数据库
php artisan vendor:publish --tag=datatables
三、建立administrator模型json
php artisan make:model Models/Administrator -m
编辑数据库迁移文件oracle
<?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'); } }
四、建立AdministratorDatatableapp
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']; }
五、建立视图文件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
六、建立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'); });
七、本地化:建立一个单独文件,如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 !
下载:项目源码