xxxcoltxxx / grid-laravel
Laravel 5 的网格包
2.2.3
2018-06-01 08:47 UTC
Requires
README
该包允许
- 形成表格数据
- 按列过滤数据和添加自己的过滤器
- 隐藏/显示表格列
- 所有过滤器都保存在 Cookie 中,因此用户在重复打开页面时可以看到上次应用过的过滤器
- 将过滤后的数据下载为 CSV
依赖项
- jquery(用于选择日期的 daterangepicker 和 bootstrap-select 库,用于选择器的样式化。未找到本地替代品)
- angularjs
- bootstrap
- font-awesome
- angular-cookies
- bootstrap-daterangepicker
- angular-daterangepicker
- bootstrap-select
- angular-bootstrap-select
- moment(由 bootstrap-daterangepicker 自动安装)
- angular-bootstrap
- angular-sanitize
以下依赖项不是必需的。您可以手动下载必要的 js 库并在模板中连接它们。安装说明中考虑了通过这些工具在 Ubuntu 14.04 上安装的方法
- npm
- bower
- gulp
- laravel-elixir
安装 npm
sudo apt-get install npm npdejs-legacy
安装 bower
npm i -g bower
安装 gulp
npm i gulp
安装 laravel-elixir(从项目目录中)
npm i
安装包
将包添加到项目中
composer require xxxcoltxxx/grid-laravel
将 ServiceProvider 添加到文件 config/app.php:
$providers => [ ... Paramonov\Grid\GridServiceProvider::class, ],
安装 js 库
bower install --save jquery
bower install --save bootstrap
bower install --save font-awesome
bower install --save angular
bower install --save angular-cookies
bower install --save bootstrap-daterangepicker
bower install --save angular-daterangepicker
bower install --save bootstrap-select
bower install --save angular-bootstrap-select
bower install --save angular-bootstrap
bower install --save angular-sanitize
复制包中的 views、lang 和 assets,您可以在以后更改和自定义它们
php artisan vendor:publish --provider="Paramonov\Grid\GridServiceProvider"
如果您有 angular 应用程序
将依赖项 ngGrid
添加到您的模块中
angular.module('app', ['ngGrid']) ...
如果您没有 angular 应用程序
只需将 angular.init.example.js
文件添加到 gulp
配置中,如下例所示。
配置 gulp
这需要将所有 js 和 css 合并成两个文件:gulpfile.js:
var elixir = require('laravel-elixir'); elixir(function(mix) { mix.scripts([ 'bower_components/jquery/dist/jquery.js', 'bower_components/angular/angular.js', 'bower_components/angular-sanitize/angular-sanitize.js', 'bower_components/bootstrap/dist/js/bootstrap.js', 'bower_components/angular-cookies/angular-cookies.js', 'bower_components/moment/moment.js', 'bower_components/bootstrap-select/dist/js/bootstrap-select.js', 'bower_components/angular-bootstrap-select/build/angular-bootstrap-select.js', 'bower_components/bootstrap-daterangepicker/daterangepicker.js', 'bower_components/angular-daterangepicker/js/angular-daterangepicker.js', 'bower_components/angular-bootstrap/ui-bootstrap-tpls.js', 'resources/assets/vendor/grid/js/angular.init.example.js', // Этот файл нужно подключить, если у вас не angular-приложение 'resources/assets/vendor/grid/js/ngGrid.js' ], 'public/js/scripts.js', '.'); mix.styles([ 'bower_components/bootstrap/dist/css/bootstrap.css', 'bower_components/font-awesome/css/font-awesome.css', 'bower_components/bootstrap-select/dist/css/bootstrap-select.css', 'bower_components/bootstrap-daterangepicker/daterangepicker.css', 'resources/assets/vendor/grid/css/grid.css' ], 'public/css/styles.css', '.'); mix.copy( 'bower_components/bootstrap/dist/fonts', 'public/fonts' ); mix.copy( 'bower_components/font-awesome/fonts', 'public/fonts' ); });
运行 gulp
在生产环境中,还可以进一步压缩,在运行 gulp 时添加 --production
键
gulp
添加表格表示
添加路由
app/Http/routes.php
... Route::get('/', ['uses' => 'UsersController@index']); # Опционально: отдельные роуты для загрузки табличных данных - json и csv Route::get('/users.json', ['uses' => 'UsersController@gridData', 'as' => 'users.json']); Route::get('/users.csv', ['uses' => 'UsersController@gridCsv', 'as' => 'users.csv']); ...
创建数据提供者
数据提供者必须扩展 GridDataProvider
类。例如,app/GridDataProviders/UsersDataProvider.php
namespace App\GridDataProviders; use App\User; use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Config; use Paramonov\Grid\GridDataProvider; use Paramonov\Grid\GridPagination; class UsersDataProvider extends GridDataProvider { /** * Запрос для выборки данных для таблицы * * @return Builder */ public function query() { return User::leftJoin('user_companies', 'user_companies.id', '=', 'users.company_id'); } /** * Пагинация * * @return GridPagination */ public function pagination() { return new GridPagination([5, 10, 15, 25, 50]); } /** * Фильтрация выборки. Аналог scope в модели * Ключи массива должны совпадать с ключами массива из view * * @return \Closure[] */ public function filters() { return [ 'id' => function(Builder $query, $search) { if (is_numeric($search)) { $query->where('users.id', $search); } }, 'name' => function(Builder $query, $search) { if (is_string($search)) { $query->whereRaw('LOWER(users.name) like LOWER(?)', ['%' . $search . '%']); } }, 'email' => function(Builder $query, $search) { if (is_string($search)) { $query->whereRaw('LOWER(users.email) like LOWER(?)', ['%' . $search . '%']); } }, 'created_at' => function(Builder $query, $search) { if ( is_array($search) && array_key_exists('startDate', $search) && array_key_exists('endDate', $search) && !is_null($search['startDate']) && !is_null($search['endDate']) ) { $start_date = Carbon::parse($search['startDate']); $end_date = Carbon::parse($search['endDate']); $query->where('created_at', '>=', $start_date); $query->where('created_at', '<=', $end_date); } }, 'updated_at' => function(Builder $query, $search) { if ( is_array($search) && array_key_exists('startDate', $search) && array_key_exists('endDate', $search) && !is_null($search['startDate']) && !is_null($search['endDate']) ) { $start_date = Carbon::parse($search['startDate']); $end_date = Carbon::parse($search['endDate']); $query->where('updated_at', '>=', $start_date); $query->where('updated_at', '<=', $end_date); } }, 'user_companies.title' => function(Builder $query, $search) { if (is_array($search)) { $query->whereIn('users.company_id', $search); } }, 'all' => function(Builder $query, $search) { if (is_string($search)) { $query->where(function(Builder $query) use ($search) { if (is_numeric($search)) { $query->where('users.id', '=', $search, 'or'); } $query->whereRaw('LOWER(users.name) like LOWER(?)', ['%' . $search . '%'], 'or'); $query->whereRaw('LOWER(users.email) like LOWER(?)', ['%' . $search . '%'], 'or'); $query->whereRaw('LOWER(user_companies.title) like LOWER(?)', ['%' . $search . '%'], 'or'); $database_driver = Config::get('database.default'); $cast = 'TEXT'; if ($database_driver == 'mysql') { $cast = 'CHAR'; } $query->whereRaw('CAST(users.created_at AS ' . $cast . ') like ?', ['%' . $search . '%'], 'or'); $query->whereRaw('CAST(users.updated_at AS ' . $cast . ') like ?', ['%' . $search . '%'], 'or'); }); } } ]; } /** * Необязательный метод * url для подгрузки данных * * @return string */ protected function dataUrl() { return route('users.json'); } /** * Необязательный метод * url для загрузки CSV-файла * * @return string */ protected function csvUrl() { return route('users.csv'); } /** * Необязательный метод * Поля типа "Дата" * * @return array */ protected function dates() { return ['created_at', 'updated_at']; } /** * Необязательный метод * Фильтры по-умолчанию * Они применяются, если фильтры отсутствуют или пользователь сбросил все фильтры * * @return array */ protected function dateFormat() { return 'd.m.Y в H:i:s'; } /** * Необязательный метод * Сортировка по умолчанию * * @return array */ protected function defaultSorting() { return ['field' => 'id', 'dir' => 'asc']; } }
创建控制器方法
app/Http/Controllers/UsersController.php
namespace App\Http\Controllers; use App\GridDataProviders\UsersDataProvider; use Illuminate\Routing\Controller; use Paramonov\Grid\GridTable; class UsersController extends Controller { protected $grid; public function __construct(UsersDataProvider $users_data_provider) { $this->grid = new GridTable($users_data_provider); } public function index() { return view('users.index', ['grid' => $this->grid]); } public function gridData() { // Если вы создавали отдельный шаблон для рендеринга ячеек, то этот шаблон передается параметром return $this->grid->getData('users.grid.cells'); } public function gridCsv() { return $this->grid->getCSV('Users'); } }
创建模板
resources/views/users/index.blade.php
<!doctype html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Пользователи</title> <link href="/css/styles.css" rel="stylesheet" /> </head> <body ng-app="app"> <div class="container"> {!! $grid->render([ 'id' => [ 'title' => 'ИД', 'type' => 'string', 'class' => 'col-lg-1' ], 'name' => [ 'title' => 'Имя', 'type' => 'string', ], 'email' => [ 'title' => 'E-Mail', 'type' => 'string', // Можно ячейку описать как Angular-выражение 'cell' => "<a href='mailto:@{{ item.email }}'>@{{ item.email }}</a>" ], 'user_companies.title' => [ 'title' => 'Компания', 'type' => 'multiselect', 'options' => \App\UserCompany::query()->lists('title', 'id') ], 'created_at' => [ 'title' => 'Создан', 'type' => 'daterange', 'data-class' => 'text-center', 'class' => 'col-lg-2' ], 'updated_at' => [ 'title' => 'Обновлен', 'type' => 'daterange', 'data-class' => 'text-center', 'class' => 'col-lg-2' ] ], // Опционально. По умолчанию подключаются эти компоненты. Это обычные views, можно создавать свои компоненты [ 'search_all', 'column_hider', 'download_csv' ]) !!} </div> <script src="/js/scripts.js" type="application/javascript"></script> </body> </html>
可选:创建渲染单元格的模板
您可以为表格中的任何单元格创建模板。它们将通过 view 在服务器上生成。Blade 模板中的每个单元格都可以在部分中定义。部分接收字段名称 $field_name
和记录 $item
resources/views/users/grid/cell.blade.php
@section('name')
<img src="https://robohash.org/{{ $item->name }}.png?size=16x16" />
{{ $item->name }}
@stop
可选:创建渲染 csv 单元的模板
您可以为 csv 中的任何单元格创建模板。当需要在一个单元格中输出非简单字段,例如姓名或用户联系信息(电话、电子邮件、skype 等)时,这很有用。如果没有模板,将输出记录的字段。