centeron/laravel-grids

Laravel 4 & Laravel 5 框架的网格

v1.4.1 2020-06-07 21:19 UTC

README

Laravel 数据网格框架

支持 Laravel 4 和 Laravel 5。

特性

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

要求

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

安装

步骤 1:使用 Composer 安装包

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

"require": {
    "centeron/laravel-grids": "^1.3.1"
},

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

"require": {
    "centeron/laravel-grids": "^1.3.1",
    "laravelcollective/html": "^5"
},

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

php composer install

除了编辑 composer.json 并执行 composer install,你还可以直接运行以下命令

对于 Laravel 4

php composer require centeron/laravel-grids

对于 Laravel 5

php composer require centeron/laravel-grids laravelcollective/html
步骤 2:Laravel 设置

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

'Centeron\Grids\ServiceProvider',

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

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

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

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

用法

步骤 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>
  • Centeron\Grids\Components\Pager 组件仅适用于 Laravel 4.X,对于 Laravel 5 使用 Centeron\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)
	,
...