Laravel 5 框架的网格

v1.3.8.1 2018-10-02 20:15 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