咱們知道,作後臺管理系統須要不少表格用來展現咱們的數據,筆者在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 !
下載:項目源碼