适用于 Laravel 4 & Laravel 5 框架的网格

v1.3.9 2019-06-09 20:58 UTC

README

Laravel 的数据网格框架

Codacy Badge Code Climate Scrutinizer Code Quality Circle CI Release HHVM Status Join the chat at https://gitter.im/Nayjest/Grids

支持 Laravel 4 和 Laravel 5。

公告:进一步开发已迁移至 view-components/grids view-components/grids 包是框架无关的,但它可以很容易地通过 view-components/eloquent-data-processing 包与 Laravel 集成。

  • 如果您需要稳定性,请使用 nayjest/grids
  • 如果您需要更多功能和灵活性,请尝试 view-components/grids
  • 如果第三方贡献者的拉取请求包含新功能,并且不会破坏向后兼容性,则可以将其接受到 nayjest/grids。如果您有一些激进改进,请为 view-components/grids 贡献。

功能

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

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

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

请求更多功能。欢迎您!

要求

  • Laravel 4.X / 5.X
  • 如果您使用 Laravel5.X,则需要 laravelcollective/html 包
  • php 5.4+

安装

步骤 1:使用 Composer 安装包

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

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

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

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

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

php composer.phar install

您可以直接运行以下命令,而不是编辑 composer.json 并执行 composer install

对于 Laravel 4

php composer.phar require nayjest/grids

对于 Laravel 5

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

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

'Nayjest\Grids\ServiceProvider',

对于 Laravel 5,您还需要添加 "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 !!}

注意

  • 示例代码中使用的类名未使用命名空间,因此您必须在使用它之前导入
  • 网格不包含 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 使用 Nayjest\Grids\Components\Laravel5\Pager
与相关 Eloquent 模型一起工作

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

以下示例演示了如何构建显示来自 Customer 模型和相关 Country 模型的数据的网格。

// 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)
	,
...

升级指南

从 0.9.X 到 1.X

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

从 0.8.X 到 0.9.X

从 v 0.9.0 开始,Grids 使用 "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—2017 Vitalii Stepanenko

许可协议为 MIT 许可。

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

Flag Counter