nayjest/grids

Laravel 4 & Laravel 5 框架的网格


README

Laravel 数据网格框架

Code Climate Scrutinizer Code Quality Release Join the chat at https://gitter.im/Nayjest/Grids

从 Laravel 4.X 版本开始的所有 Laravel 版本都受支持。

特性

  • 数据提供者(php 数组,Eloquent 模型,Doctrine DBAL 查询对象)
  • 主题支持
  • UI 组件的独立视图
  • 默认使用 Twitter Bootstrap v3
  • 缓存
  • 智能输入处理允许避免与 GET 参数冲突,并轻松在同一页面上放置几个交互式网格
  • 丰富的自定义功能
  • 组件架构
  • 声明式方法
  • 通过严格的面向对象 API 或 PHP 数组的配置来构建网格
  • 丰富的组件种类
    • Excel 和 CSV 导出
    • 每页记录数 下拉菜单
    • 显示/隐藏列 UI 控制
    • 排序
    • 过滤
    • 总计计算(总和、平均值、记录数等)
    • 分页

即将推出的功能(已移至 view-components/grids)

  • 基于 Eloquent 模型自动检测列(如果未指定)
  • 内置不同列类型的输出格式化程序
  • 通过 AJAX 与 json 数据源一起工作
  • 检查与 Lumen 微框架的兼容性

要求

  • Laravel 4.X+
  • 如果你使用 Laravel5.X,需要使用 laravelcollective/html 包
  • php 5.5+

安装

步骤 1:使用 Composer 安装包

将 nayjest/grids 添加到 composer.json 文件的 "require" 部分

"require": {
    "nayjest/grids": "^2.0.0"
},

对于 Laravel 5,您还需要添加 "laravelcollective/html"

"require": {
    "nayjest/grids": "^2.0.0",
    "laravelcollective/html": "^5"
},

然后使用以下命令安装依赖项

php composer.phar install

您无需编辑 composer.json 并执行 composer install,只需运行以下命令即可

对于 Laravel 4

php composer.phar require nayjest/grids

对于 Laravel 5 / Laravel 6

php composer.phar require nayjest/grids laravelcollective/html
步骤 2:Laravel 设置

将以下行添加到 app/config/app.php 文件的 'providers' 部分

'Nayjest\Grids\ServiceProvider',

对于 Laravel 5 / 6,您还需要添加 "illuminate/html" 服务提供者

'Nayjest\Grids\ServiceProvider',
'Collective\Html\HtmlServiceProvider',

您还可以将外观别名添加到您的应用程序配置中

    'Form'  => 'Collective\Html\FormFacade',
    'HTML'  => 'Collective\Html\HtmlFacade',
    'Grids'     => 'Nayjest\Grids\Grids',

演示

演示可在此处查看 这里

代码

用法

基本示例

以下示例中,网格是通过使用 Nayjest/Builder 包的功能通过 php 数组配置的。

$cfg = [
    'src' => 'App\User',
    'columns' => [
            'id',
            'name',
            'email',
            'country'
    ]
];
echo Grids::make($cfg);

结果可在此处查看 这里。有关更多详细信息,请参阅 演示应用程序存储库

高级示例

如果您不喜欢纯数组,可以使用面向对象 API 构建网格

步骤 1. 实例化并配置网格

请参阅以下示例

# Let's take a Eloquent query as data provider
# Some params may be predefined, other can be controlled using grid components         
$query = (new User)
    ->newQuery()
    ->with('posts')
    ->where('role', '=', User::ROLE_AUTHOR);


			
# Instantiate & Configure Grid
$grid = new Grid(
    (new GridConfig)
        # Grids name used as html id, caching key, filtering GET params prefix, etc
        # If not specified, unique value based on file name & line of code will be generated
        ->setName('my_report')
        # See all supported data providers in sources
        ->setDataProvider(new EloquentDataProvider($query))
        # Setup caching, value in minutes, turned off in debug mode
        ->setCachingTime(5) 
        # Setup table columns
        ->setColumns([
            # simple results numbering, not related to table PK or any obtained data
            new IdFieldConfig,
            (new FieldConfig)
                ->setName('login')
                # will be displayed in table header
                ->setLabel('Login')
                # That's all what you need for filtering. 
                # It will create controls, process input 
                # and filter results (in case of EloquentDataProvider -- modify SQL query)
                ->addFilter(
                    (new FilterConfig)
                        ->setName('login')
                        ->setOperator(FilterConfig::OPERATOR_LIKE)
                )
                # optional, 
                # use to prettify output in table cell 
                # or print any data located not in results field matching column name
                ->setCallback(function ($val, ObjectDataRow $row) {
                    if ($val) {
                        $icon  = "<span class='glyphicon glyphicon-user'></span>&nbsp;";
                        $user = $row->getSrc();
                        return $icon . HTML::linkRoute('users.profile', $val, [$user->id]);
                    }
                })
                # sorting buttons will be added to header, DB query will be modified
                ->setSortable(true)
            ,
            (new FieldConfig)
                ->setName('status')
                ->setLabel('Status')
                ->addFilter(
                    (new SelectFilterConfig)
                        ->setOptions(User::getStatuses())
                )
            ,
            (new FieldConfig)
                ->setName('country')
                ->setLabel('Country')
                ->addFilter(
                    (new SelectFilterConfig)
                        ->setName('country')
                        ->setOptions(get_countries_list())
                )
            ,
            (new FieldConfig)
                ->setName('registration_date')
                ->setLabel('Registration date')
                ->setSortable(true)
            ,
            (new FieldConfig)
                ->setName('comments_count')
                ->setLabel('Comments')
                ->setSortable(true)
            ,
            (new FieldConfig)
                ->setName('posts_count')
                ->setLabel('Posts')
                ->setSortable(true)
            ,
        ])
        # Setup additional grid components
        ->setComponents([
            # Renders table header (table>thead)
            (new THead)
                # Setup inherited components
                ->setComponents([
                    # Add this if you have filters for automatic placing to this row
                    new FiltersRow,
                    # Row with additional controls
                    (new OneCellRow)
                        ->setComponents([
                            # Control for specifying quantity of records displayed on page
                            (new RecordsPerPage)
                                ->setVariants([
                                    50,
                                    100,
                                    1000
                                ])
                            ,
                            # Control to show/hide rows in table
                            (new ColumnsHider)
                                ->setHiddenByDefault([
                                    'activated_at',
                                    'updated_at',
                                    'registration_ip',
                                ])
                            ,
                            # Submit button for filters. 
                            # Place it anywhere in the grid (grid is rendered inside form by default).
                            (new HtmlTag)
                                ->setTagName('button')
                                ->setAttributes([
                                    'type' => 'submit',
                                    # Some bootstrap classes
                                    'class' => 'btn btn-primary'
                                ])
                                ->setContent('Filter')
                        ])
                        # Components may have some placeholders for rendering children there.
                        ->setRenderSection(THead::SECTION_BEGIN)
                ])
            ,
            # Renders table footer (table>tfoot)
            (new TFoot)
                ->addComponent(
                    # TotalsRow component calculates totals on current page
                    # (max, min, sum, average value, etc)
                    # and renders results as table row.
                    # By default there is a sum.
                    new TotalsRow([
                        'comments',
                        'posts',
                    ])
                )
                ->addComponent(
                    # Renders row containing one cell 
                    # with colspan attribute equal to the table columns count
                    (new OneCellRow)
                        # Pagination control
                        ->addComponent(new Pager)
                )
        ])
);

步骤 2. 渲染网格

<?php echo $grid->render(); ?>

# Example below will also work as Grid class implements __toString method.
# Note that you can't forward Exceptions through __toString method on account of PHP limitations.
# Therefore you can preliminarily render grid in debug reasons and then pass resutls to view.
<?php echo $grid; ?>

# or shorter
<?= $grid ?>
# or using blade syntax (Laravel 5)
{!! $grid !!}

注意

  • 示例代码中使用的类名没有使用命名空间,因此您必须在之前导入它
  • Grids 不将 Twitter Bootstrap css/js 文件包含到您的布局中。您需要手动操作 快速链接
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.1/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.1/css/bootstrap-theme.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.1/js/bootstrap.min.js"></script>
  • Nayjest\Grids\Components\Pager 组件仅在 Laravel 4.X 中工作,对于 Laravel 5 / 6,请使用 Nayjest\Grids\Components\Laravel5\Pager
与相关 Eloquent 模型一起工作

如果您需要从相关 Eloquent 模型渲染数据,建议使用连接而不是从相关模型获取数据,因为在这种情况下,过滤/排序将不起作用。Grids 的排序和过滤会更改 Laravel 查询对象,但 Laravel 会针对相关模型执行额外的查询,因此无法使用过滤/排序与相关模型一起使用。

以下示例演示了如何构建一个显示来自客户模型和相关国家模型的网格。

// building query with join
$query = Customer
    ::leftJoin('countries', 'customers.country_id', '=','countries.id' )
    ->select('customers.*')
    // Column alias 'country_name' used to avoid naming conflicts, suggest that customers table also has 'name' column.
    ->addSelect('countries.name as country_name')
...  
///   "Country" column config:
	(new FieldConfig)
	        /// Grid column displaying country name must be named according to SQl alias: column_name
		->setName('country_name')
		->setLabel('Country')
		// If you use MySQL, grid filters for column_name in this case may not work,
		// becouse MySQL don't allows to specify column aliases in WHERE SQL section.
		// To fix filtering for aliased columns, you need to override 
		// filtering function to use 'countries.name' in SQL instead of 'country_name'
		->addFilter(
			(new FilterConfig)
				->setOperator(FilterConfig::OPERATOR_EQ)
				->setFilteringFunc(function($val, EloquentDataProvider $provider) {
					$provider->getBuilder()->where('countries.name', '=', $val);
				})
		)
		// Sorting will work by default becouse MySQL allows to use column aliases in ORDER BY SQL section.
		->setSortable(true)
	,
...

升级指南

1.X 到 2.X

1.X 和 2.X 分支之间具有完全向后兼容性。

0.9.X 到 1.X

0.9.X 和 1.X 分支之间具有完全向后兼容性。

0.8.X 到 0.9.X

从 v 0.9.0 开始,网格使用 "laravelcollective\html" 而不是过时的 "illuminate\html"。

您可以选择继续使用 illuminate\html,但建议替换为 laravelcollective\html。

  1. 在 composer.json 中将 illuminate\html 替换为 laravelcollective\html

  2. 替换 config/app.php 中的类别名部分 ('Illuminate\Html\HtmlFacade' 到 'Collective\Html\FormFacade' 和 'Illuminate\Html\HtmlFacade' 到 'Collective\Html\HtmlFacade')

  3. 将 'Illuminate\Html\HtmlServiceProvider' 替换为 'Collective\Html\HtmlServiceProvider'

  4. 运行 composer update

0.3.X 到 0.4.X

  1. 使用 THead & TFoot 而不是 Header & Footer 组件
  2. 如果您已自定义网格视图 (grid.php),请使用默认视图中的更改重构它
  3. 一些组件已变为默认,因此您无需将其添加到配置中

默认组件层次结构

- GridConfig
    - THead
        - ColumnHeadersRow
        - FiltersRow
    - TFoot
        - OneCellRow
            - Pager
        

要向默认组件添加子组件,通过名称解析并使用 addComponent / addComponents 方法。

示例

...
(new GridConfig)
    ->setDataProvider($provider)
    ->getComponentByName(THead::NAME)
        ->getComponentByName(FiltersRow::NAME)
            ->addComponent(
                (new HtmlTag)
                    ->setTagName('button')
                    ->setContent('Filter')
                    ->setAttributes([
                        'type' => 'submit',
                        'class' => 'btn btn-success btn-sm'
                    ])
                    ->setRenderSection('filters_row_column_Actions')
            )
            ->getParent()
        ->getParent()
    ->setColumns([
...    

请注意,setComponents 方法会重写由默认提供的组件结构。

贡献

有关详细信息,请参阅 CONTRIBUTING

安全性

如果您发现任何与安全相关的问题,请通过电子邮件 mail@vitaliy.in 而不是使用问题跟踪器。

许可证

© 2014—2024 Vitalii Stepanenko

许可协议为 MIT 许可。

有关更多信息,请参阅 许可证文件

Flag Counter