3

我们知道,做后台管理系统需要很多表格用来展示我们的数据,笔者在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 !
下载:项目源码


kaihongChan
29 声望2 粉丝

混迹行业的程序猿