evgeniy-silantev/laravel-table

使用 Laravel 生成表格。

1.2.9 2020-03-19 12:25 UTC

README

Source Code Latest Version Total Downloads License: MIT Build Status Coverage Status Quality Score

Laravel Table 允许您通过 PHP 代码直接在视图中渲染表格。
此软件包附带了对 Bootstrap 4.*FontAwesome 5 的预配置。
然而,模板的自定义使其非常容易与其他 UI 框架一起使用。

兼容性

用法

在您的代码中某处准备表格配置,并将其传递到视图中

$table = (new \Okipa\LaravelTable\Table)->model(\App\News::class)->routes([
    'index'   => ['name' => 'users.index'],
    'create'  => ['name' => 'user.create'],
    'edit'    => ['name' => 'user.edit'],
    'destroy' => ['name' => 'user.destroy'],
])->destroyConfirmationHtmlAttributes(function (User $user) {
    return [
        'data-confirm' => 'Are you sure you want to delete the user ' . $user->name . ' ?',
    ];
});
$table->column('first_name')->sortable(true)->searchable();
$table->column('last_name')->sortable()->searchable();
$table->column('email')->sortable()->searchable();

在您的视图中,只需像这样渲染您的表格

{{ $table }}

目录

安装

  • 使用 composer 安装包
composer require "evgeniy-silantev/laravel-table:^1.0"

配置

发布包配置并覆盖现有配置值

php artisan vendor:publish --tag=laravel-table:config

自定义翻译

要自定义现有翻译,发布包的翻译文件以进行所需更改

php artisan vendor:publish --tag=laravel-table:translations

自定义模板

自定义使用的模板以使此包满足您的需求。
使用命令发布视图

php artisan vendor:publish --tag=laravel-table:views

表格 API

⚠️ 所有以下方法都可以与 \Okipa\LaravelTable\Table 对象链式调用 除了 ->column()->result() 方法(分别返回 \Okipa\LaravelTable\Column\Okipa\LaravelTable\Result 对象)。

->model()

设置在表格生成过程中使用的模型。

备注

  • 签名: model(string $tableModel): \Okipa\LaravelTable\Table
  • 必需

用例示例

(new \Okipa\LaravelTable\Table)->model(\App\News::class);

->identifier()

设置表格标识符,以便自动生成其 ID,并在单个视图中使用多个表格的情况下自定义所有交互字段:对表格的交互,如排序、搜索等,只会影响标识的表格。

备注

  • 签名: identifier(string $identifier): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->identifier('Your identifier');

->request()

设置用于表格生成的请求。

备注

  • 签名: request(Request $request): \Okipa\LaravelTable\Table
  • 可选

用例示例

// example in a controller
public function index(Request $request) {
    app(\Okipa\LaravelTable\\Okipa\LaravelTable\Table::class)->request($request);
    // ...
}

->routes()

设置在表格生成过程中使用的路由。
路由声明将用于以下功能

  • index(必需):用于行数定义、排序和搜索功能。
  • create(可选):如果声明此路由,则显示 创建 按钮。按钮使用此路由重定向到模型创建页面。
  • edit(可选):如果声明了此路由,则在每个行中显示编辑按钮。此路由用于跳转到模型编辑页面。
  • destroy(可选):如果声明了此路由,则在每个行中显示删除按钮。此路由用于触发模型删除操作。
  • show(可选):如果声明了此路由,则在每个行中显示显示按钮。此路由用于跳转到模型显示页面。

注意

  • 签名: routes(array $routes): \Okipa\LaravelTable\Table
  • 必需
  • 每个路由必须使用以下结构进行定义
// example
[
    'index' => [
        // required
        'name' => 'news.index',
        // optional
        'params' => [
            // set route params
            // or do not declare it
        ]
    ]
];
  • ⚠️由于当前模型始终作为参数传递给editdestroyshow路由,因此您不需要在->routes()调用中定义它。您还应仔细声明路由以避免错误。请参阅以下示例
    // assuming your declared your route with implicit binding :
    Route::get('parent/{$parent}/user/edit/{$user}/child/{$child}', 'UsersController@edit')->name('user.edit');
    // you'll have to declare your params with keys as following :
    (new Table)->model(User::class)->routes([
        // ...
        'edit'    => ['name'=> 'user.edit', 'params' => ['parent' => $parent, 'child' => $child]],
        // ...
    ])
    // because the route will be generated with the table related model as first param (the params order differs from the declaration) :
    route('user.edit, [$user, 'parent' => $parent, 'child' => $child]);
    // now imagine your route is declared with the table related model as first param like this :
    Route::get('/user/edit/{$user}/child/{$child}/{otherParam}', 'UsersController@edit')->name('user.edit');
    // in this case only, you will be able to declare your routes without keys :
    (new Table)->model(User::class)->routes([
        // ...
        'edit'    => ['name'=> 'user.edit', 'params' => [$child, 'otherValue']],
        // ...
    ])
    // because the route params are given in the same order as the route declaration :
    route('user.edit, [$user, $child, 'otherValue']);

用例示例

(new \Okipa\LaravelTable\Table)->routes([
    'index' => ['name' => 'news.index'],
    'create' => ['name' => 'news.create', 'params' => ['param1' => 'value1']],
    'edit' => ['name' => 'news.edit', 'params' => ['param2' => 'value2']],
    'destroy' => ['name' => 'news.destroy'],
    'show' => ['name' => 'news.show'],
]);

->rowsNumber

覆盖配置默认的表格显示行数。
默认的显示行数由config('laravel-table.value.rowsNumber')配置值定义。
设置为false以显示数据库中包含的所有模型。

注意

  • 签名: rowsNumber(?int $rows): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->rowsNumber(50);
// or
(new \Okipa\LaravelTable\Table)->rowsNumber(null);

->rowsNumberSelectionActivation()

覆盖默认行数选择激活状态。
调用此方法将显示一个行数输入框,用户可以选择要显示的行数。
默认行数选择激活状态由config('laravel-table.value.rowsNumberSelectionActivation')值管理。

注意`

  • 签名: rowsNumberSelectionActivation($activate = true): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->rowsNumberSelectionActivation(false);

->query()

设置在表格生成过程中要执行查询闭包。
例如,您可以在其中定义您的联接表。
闭包让您操作以下属性:$query

注意

  • 签名: query(Closure $queryClosure): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->query(function($query){
    $query->select('users.*');
    $query->addSelect('companies.name as company');
    $query->join('users', 'users.id', '=', 'companies.owner_id');
});

->appends()

添加要附加到分页器和以下表格操作的数组参数

  • 行数选择
  • 搜索
  • 搜索取消
  • 排序。

注意

  • 签名: appends(array $appendedValues): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->appends(request()->only('status'));

->containerClasses()

覆盖默认表格容器类。
默认容器类由config('laravel-table.classes.container')配置值定义。

注意

  • 签名: containerClasses(array $containerClasses): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->containerClasses(['set', 'your', 'classes']);

->tableClasses()

覆盖默认表格类。
默认表格类由config('laravel-table.classes.table')配置值定义。

注意

  • 签名: tableClasses(array $tableClasses): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->tableClasses(['set', 'your', 'classes']);

->trClasses()

覆盖默认表格tr类。
默认tr类由config('laravel-table.classes.tr')配置值定义。

注意

  • 签名: trClasses(array $trClasses): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->trClasses(['set', 'your', 'classes']);

->thClasses()

覆盖默认表格tr类。
默认th类由config('laravel-table.classes.th')配置值定义。

注意

  • 签名: thClasses(array $thClasses): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->thClasses(['set', 'your', 'classes']);

->tdClasses()

覆盖默认表格td类。
默认td类由config('laravel-table.classes.td')配置值定义。

注意

  • 签名: tdClasses(array $tdClasses): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->tdClasses(['set', 'your', 'classes']);

->rowsConditionalClasses()

在给定的条件满足时设置行类。
闭包让您操作以下属性:$model注意:

  • 签名: rowsConditionalClasses(Closure $rowClassesClosure, array $rowClasses): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->rowsConditionalClasses(function($model){
    return $model->hasParticularAttribute;
}, ['set', 'your', 'classes']);

->destroyConfirmationHtmlAttributes()

在删除按钮上定义HTML属性以处理动态JavaScript删除确认。
闭包让您操作以下属性:$model
注意:删除确认的管理由您负责,如果您没有设置JavaScript处理程序来请求确认,则将直接执行删除操作。

注意

  • 签名: destroyConfirmationHtmlAttributes(Closure $destroyConfirmationClosure): \Okipa\LaravelTable\Table
  • 可选(但强烈建议!)

用例示例

(new \Okipa\LaravelTable\Table)->destroyHtmlAttributes(function($model){
    return ['data-confirm' => __('Are you sure you want to delete the user :name ?', [
        'name' => $model->name
    ])];
});

JavaScript代码示例

// example of javascript snippet to ask a confirmation before executing the action
// this example assume that a bootstrap modal component has been included in your view
// https://bootstrap.ac.cn/docs/4.3/components/modal/#modal-components
const destroyButton = $('form.destroy button[type="submit"]');
destroyButton.click((e) => {
  e.preventDefault();
  const $this = $(e.target);
  const message = $this.data("confirm");
  const confirmationModal = $("#confirmationModal");
  confirmationModal.find(".modal-body").text(message);
  confirmationModal.modal("show");
});

->disableRows()

设置在表格生成过程中将执行的禁用行关闭。
可选的第二个参数允许您覆盖将应用于禁用行的类。
默认情况下,应用配置值“config('laravel-table.classes.disabled')”。
例如,您可以通过禁用当前登录用户来防止他在表格中被编辑或删除。
闭包让您操作以下属性:$model

注意

  • 签名: disableRows(Closure $rowDisableClosure, array $classes = []): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->disableRows(function($user){
    return $user->id = auth()->id;
}, ['bg-danger', 'text-primary']);

->tableTemplate()

为表格组件设置自定义模板路径。
默认表格模板路径在配置值 config('laravel-table.template.table') 中定义。

注意

  • 签名: tableTemplate(string $tableComponentPath): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->tableTemplate('tailwindCss.table');

->theadTemplate()

为 thead 组件设置自定义模板路径。
默认 thead 模板路径在配置值 config('laravel-table.template.thead') 中定义。

注意

  • 签名: theadTemplate(string $theadComponentPath): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->theadTemplate('tailwindCss.thead');

->tbodyTemplate()

为 tbody 组件设置自定义模板路径。
默认 tbody 模板路径在配置值 config('laravel-table.template.tbody') 中定义。

注意

  • 签名: tbodyTemplate(string $tbodyComponentPath): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->tbodyTemplate('tailwindCss.tbody');

->resultsTemplate()

为 results 组件设置自定义模板路径。
默认 results 模板路径在配置值 config('laravel-table.template.results') 中定义。

注意

  • 签名: resultsTemplate(string $resultsComponentPath): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->resultsComponentPath('tailwindCss.results');

->tfootTemplate()

为 tfoot 组件设置自定义模板路径。
默认 tfoot 模板路径在配置值 config('laravel-table.template.tfoot') 中定义。

注意

  • 签名: tfootTemplate(string $tfootComponentPath): \Okipa\LaravelTable\Table
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->tfootTemplate('tailwindCss.tfoot');

->column()

添加将在表格中显示的列。
如果列未声明为可排序或可搜索,则列键是可选的。

注意

  • 签名: column(string $databaseColumn = null): \Okipa\LaravelTable\Column
  • 必需
  • **警告**:此方法不应与其他 \Okipa\LaravelTable\Table 方法链式调用,因为它返回一个 \Okipa\LaravelTable\Column 对象。请参阅用法示例以检查如何使用此方法。

用例示例

(new \Okipa\LaravelTable\Table)->column('email');

->result()

添加将在表格底部显示的结果行。

注意

  • 签名: result(): Result
  • 可选
  • **警告**:此方法不应与其他 \Okipa\LaravelTable\Table 方法链式调用,因为它返回一个 \Okipa\LaravelTable\Result 对象。请参阅用法示例以检查如何使用此方法。

用例示例

(new \Okipa\LaravelTable\Table)->result();

列 API

⚠️ 所有列方法均可与 \Okipa\LaravelTable\Column 对象链式调用。

->classes()

为仅此列应用自定义类。

注意

  • 签名: classes(array $classes): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column()->classes(['font-weight-bold']);

->title()

设置列标题或覆盖默认标题(由列名生成的 __('validation.attributes.[column key]))。

注意

  • 签名: title(string $title = null): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column()->title('E-mail');

->sortable()

使列可排序。
您还可以选择设置默认排序的列。
如果没有列默认排序,则第一个将自动排序。

注意

  • 签名: sortable(bool $sortByDefault = false, $sortDirection = 'asc'): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column('email')->sortable();
// alternative
(new \Okipa\LaravelTable\Table)->column('email')->sortable(true, 'desc');

->searchable()

使列可搜索。
第一个参数允许您指定搜索的数据库表(可以引用数据库表别名)。
第二个参数允许您指定搜索的数据库属性(如果没有指定,则搜索表数据库列)。

注意

  • 签名: public function searchable(string $databaseSearchedTable = null, array $databaseSearchedColumns = []): \Okipa\LaravelTable\Column
  • 可选

用例示例

// example 1
(new \Okipa\LaravelTable\Table)->column('email')->searchable();
// example 2
$table = (new \Okipa\LaravelTable\Table)->model(\App\User::class)->query(function($query) {
    $query->select('users.*');
    $query->addSelect('companies.name as company');
    $query->join('companies', 'companies.owner_id', '=', 'users.id');
});
$table->column('company')->searchable('companies', ['name']);
// example 3
$table = (new \Okipa\LaravelTable\Table)->model(\App\User::class)->query(function($query) {
    $query->select('users.*');
    $query->addSelect(\DB::raw('CONCAT(companies.name, " ", companies.activity) as company'));
    $query->join('companies as companiesAliasedTable', 'companies.owner_id', '=', 'users.id');
});
$table->column('company')->searchable('companiesAliasedTable', ['name', 'activity']);

->dateTimeFormat()

设置日期时间、日期或时间数据库列的格式(可选)。
(在内部使用 Carbon::parse($value)->format($format) 方法)。

注意

  • 签名: dateTimeFormat(string $dateTimeFormat): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column('created_at')->dateTimeFormat('d/m/Y H:i');

->button()

将列显示为具有给定类的按钮。

注意

  • 签名: button(array $buttonClasses = []): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column('email')->button(['btn', 'btn-sm', 'btn-primary']);

->link()

将列值包装在 <a></a> 组件中。
您可以将链接声明为一个字符串或一个闭包,这将允许您操作以下属性: $model$column
如果没有声明URL,则将其设置为列值。

注意

  • 签名: link($url = null): \Okipa\LaravelTable\Column
  • 可选

用例示例

// example 1
(new \Okipa\LaravelTable\Table)->column('url')->link();
// example 2
(new \Okipa\LaravelTable\Table)->column()->link(route('news.index'));
// example 3
(new \Okipa\LaravelTable\Table)->column()->link(function($news) {
    return route('news.show', $news);
});

->icon()

在显示的值之前添加一个图标。
如果要将图标显示出来,即使列没有值,也将第二个参数设置为true。

注意

  • 签名: icon(string $icon, bool $displaydisplayIconWhenNoValue = false): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column('email')->icon('<i class="fas fa-envelope"></i>', true);

->stringLimit()

设置字符串值的显示限制。
当达到限制时显示"..."。

注意

  • 签名: stringLimit(int $stringLimit): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column('email')->stringLimit(30);

->value()

为列显示自定义值。
闭包允许您操作以下属性: $model$column

注意

  • 签名: value(Closure $valueClosure): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column()->value(function($user) {
    return config('users.type.' . $user->type_id);
});

->html()

为列显示自定义HTML。
闭包允许您操作以下属性: $model$column

注意

  • 签名: html(Closure $htmlClosure): \Okipa\LaravelTable\Column
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->column()->html(function($user) {
    return '<div>' . $user->first_name . '</div>';
});

结果 API

⚠️ 所有结果方法都可以与 \Okipa\LaravelTable\Result 对象链式调用。

->title()

设置结果行的标题。

注意

  • 签名: title(string $title): \Okipa\LaravelTable\Result
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->result()->title('Turnover total');

->html()

显示结果行的HTML输出。
闭包允许您操作以下属性: $displayedList

注意

  • 签名: html(Closure $htmlClosure): \Okipa\LaravelTable\Result
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->result()->html(function($displayedList) {
    return $displayedList->sum('turnover');
});

->classes()

覆盖默认的结果类,并且仅在此结果行上应用给定的类。
默认的结果类由 config('laravel-table.classes.results') 的值管理。

注意

  • 签名: classes(array $classes): \Okipa\LaravelTable\Result
  • 可选

用例示例

(new \Okipa\LaravelTable\Table)->result()->classes(['bg-dark', 'text-white', 'font-weight-bold']);

提示

  • 请求:不需要将请求传输到表格:它系统性地使用 request() 助手提供的当前请求来获取要显示的行数以及搜索、排序或分页数据。但是,如果您需要将特定的请求传递给表格,您可以使用 ->request() 方法。
  • 列标题:默认情况下,表格列标题采用以下值: __('validation.attributes.[databaseColumn])。您可以使用 title() 方法设置自定义标题。
  • 列显示组合:以下表格列方法可以组合起来显示所需的结果。如果您无法获得所需的结果,您应该使用 ->html() 方法来构建自定义显示。
    • ->button()
    • ->link()
    • ->icon()
    • ->stringLimit()
    • ->value()

用法示例

基本

在您的控制器中,只需像以下示例那样调用包来生成您的表格

$table = (new \Okipa\LaravelTable\Table)->model(\App\News::class)->routes(['index' => ['name' => 'news.index']]);
$table->column('title')->sortable()->searchable();

然后,将您的 $table 对象发送到您的视图,并按如下方式渲染表格

{{ $table }}

这就完成了!

高级

如果您需要用于更高级用途的表格,例如多语言项目,以下是在控制器中可以执行的一些示例

$table = (new \Okipa\LaravelTable\Table)->model(\App\News::class)
    ->request($request)
    ->routes([
        'index'      => ['name' => 'news.index'],
        'create'     => ['name' => 'news.create'],
        'edit'       => ['name' => 'news.edit'],
        'destroy'    => ['name' => 'news.destroy'],
        'show'    => ['name' => 'news.show'],
    ])
    ->rowsNumber(50) // or set `false` to get all the items contained in database
    ->rowsNumberSelectionActivation(false)
    ->query(function ($query) use ($category_id) {
        // some examples of what you can do
        $query->select('news.*');
        // add a constraint
        $query->where('category_id', $category_id);
        // get value stored in a json field
        $query->addSelect('news.json_field->>json_attribute as json_attribute');
        // get a formatted value form a pivot table
        $query->selectRaw('count(comments.id) as comments_count');
        $query->leftJoin('news_commment', 'news_commment.news_id', '=', 'news.id');
        $query->leftJoin('comments', 'comments.id', '=', 'news_commment.comment_id');
        $query->groupBy('comments.id');
        // alias a value to make it available from the column model
        $query->addSelect('users.name as author');
        $query->join('users', 'users.id', '=', 'news.author_id');
    })
    ->disableRows(function($model){
        return $model->id === 1 || $model->id === 2;
    }, ['disabled', 'bg-secondary'])
    ->rowsConditionalClasses(function($model){
        return $model->id === 3;
    }, ['highlighted', 'bg-success']);
$table->column('image')->html(function ($model, $column) {
    return $model->{$column->databaseDefaultColumn}
        ? '<img src="' . $model->{$column->databaseDefaultColumn} . '" alt="' .  $model->title . '">'
        : null;
});
$table->column('title')->sortable()->searchable();
$table->column('content')->stringLimit(30);
$table->column('author')->sortable()->searchable('user', ['name']);
$table->column('category_id')
    ->title('Category custom name')
    ->icon('your-icon')
    ->button(['btn', 'btn-sm', 'btn-outline-primary'])
    ->value(function ($model, $column) {
        return config('news.category.' . $model->{$column->databaseDefaultColumn});
    });
$table->column()->link(function($model){
    return route('news.show', $model);
})->button(['btn', 'btn-sm', 'btn-primary']);
$table->column('released_at')->sortable()->dateTimeFormat('d/m/Y H:i:s');
$table->result()->title('Total of comments')->html(function($displayedList){
    return $displayedList->sum('comments_count');
});

测试

composer test

变更日志

请参阅 CHANGELOG 了解最近的变化。

贡献

请参阅 CONTRIBUTING 了解详细信息。

致谢

许可证

MIT许可证(MIT)。请参阅 许可证文件 了解更多信息。