domenik88/grid-bundle

symfony4 或 symfony5 的 Datagrid,支持 DoctrineORM 3.0 及以后版本

安装: 2

依赖者: 0

建议者: 0

安全性: 0

星级: 0

关注者: 1

分支: 11

类型:symfony-bundle

7.2.2 2021-05-11 16:43 UTC

README

从 Doctrine ORM 实体生成可搜索的 Grid

  • 使用 jQuery DataTablesjqGrid(*), 或样式化 HTML 表格(*)
  • 使用 Bootstrap 轻松定制样式
  • 自定义列和其他...
  • (从 2.0 版本开始):易于安装,快速入门

(*) 仅在 DataTables 中支持搜索功能

使用 jqGrid、jQuery DataTables 或样式化 HTML 表格渲染可定制的表格。

支持 Doctrine ORM 和 Doctrine MongoDB ODM

Screenshot

安装

Symfony 4/5

    composer.phar require mmucklo/grid-bundle

您可能会看到如下内容(如果提示,请回答 'y')

  -  WARNING  mmucklo/grid-bundle (>=5.0): From github.com/symfony/recipes-contrib:master
    The recipe for this package comes from the "contrib" repository, which is open to community contributions.
    Review the recipe at https://github.com/symfony/recipes-contrib/tree/master/mmucklo/grid-bundle/4.0

    Do you want to execute this recipe?
    [y] Yes
    [n] No
    [a] Yes for all packages, only for the current installation session
    [p] Yes permanently, never ask again for this project
    (defaults to n): y
  - Configuring mmucklo/grid-bundle (>=5.0): From github.com/symfony/recipes-contrib:master

用法

入门指南

安装后,所有带有 Grid 注解的实体和文档都应在 dtc_grid 路由下可用

设置页面网格有两种推荐方式:通过注解或通过反射

反射

通过在 config/packages/dtc_grid.yaml 配置文件(或 symfony <= 3.4 的 config.yml)中设置 reflections: allowed_entities: [...] 参数,可以实现自动网格设置(

dtc_grid:
    reflection:
        # allow any entity to be shown via the /dtc_grid route
        # allowed_entities: ~, '*', or an array of entity names [ 'App:Product', 'App:Category', ... ]
        #  ~ - no entities allowed for reflection
        #  * - all entities allowed for reflection
        #  [ 'App:Product', 'App:Category' ] - only App:Product and App:Category allowed
        allowed_entities: ~

(新功能 6.0) 网格 yaml 文件定义

您可以将网格列定义放置在自定义 yaml 文件中

步骤 1 - 创建 yaml 文件
# File location(s):
#   - symfony 4+: config/dtc_grid/*.yaml (will load all *.yaml files in this directory)
#   - custom (bundles): add the following to a CompilerPass:
#        # $cacheDir = $container->getParameter('kernel.cache_dir');
#        \Dtc\GridBundle\Grid\Source\ColumnSource::cacheClassesFromFile($cacheDir, $filename);
App\User:
  columns:
    id:
      sortable: true
    username:
      sortable: true
      searchable: true
    email:
      searchable: true
    createdAt:
      sortable: true
    updatedAt:
      sortable: true
    status:
      sortable: true
      searchable: true
  actions:
    -
      label: Show
      type: show
      route: dtc_grid_show
    -
      label: Archive
      type: delete
      route: dtc_grid_delete
  sort:
    id: ASC

App\Article:
  columns:
    id:
      sortable: true
    userId:
      sortable: true
    createdAt:
      sortable: true
    updatedAt:
      sortable: true
    subject:
      searchable: true
    status:
      sortable: true
  actions:
    -
      label: Show
      type: show
      route: dtc_grid_show
    -
      label: Custom
      onclick: "alert('custom action')"
      button_class: btn-info
  sort:
    createdAt: DESC

注解简单示例

注意:此示例仍然使用反射来发现列,但如果您想自定义显示的列以及哪些列显示,请参阅下面的“自定义列”部分

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Dtc\GridBundle\Annotation as Grid;

/**
 * Class User
 * @Grid\Grid
 * @ORM\Entity
 * @package App\Entity
 */
class User {
    //...
}

现在在添加注解后,您可能需要执行以下操作

    bin/console cache:clear
    bin/console cache:warmup

访问网格

您可以通过以下 URL 访问网格,而不需要在任何地方嵌入它

  • 路由:dtc_grid/dtc_grid/grid?class=App:User
  • 参数
    • class=[文档或实体]
      • 这可以是完全命名空间化的类名或 symfony 风格的实体/文档格式,用 ':' 分隔
        • 例如:'App:User' 或 'App\Entity\User'
    • type=[datatables|table|jq_grid]

示例

# A default HTML-based table
# (warning: if your table is large, skip this example, and try the paginated datatables path below)


# Datatables
/dtc_grid/grid?class=App:User&type=datatables

# Full Class syntax 
/dtc_grid/grid?class=App\Entity\User&type=datatables
 
# MongoDB ODM examples
/dtc_grid/grid?class=App:Event&type=datatables
/dtc_grid/grid?class=App\Document\Event&type=datatables

# Other types of tables
/dtc_grid/grid?class=App:Event&type=jq_grid
/dtc_grid/grid?class=App:Event&type=table

 

注意 - 安全性

对于生产系统,您可能需要在 security.yml 中添加 ^/dtc_grid 路径,并使其成为防火墙/仅管理员访问

security:
    # ...
    access_control:
        # ...
        - { path: ^/dtc_grid, roles: ROLE_ADMIN }

添加操作

目前有几个操作可以添加到您的网格中,这些操作将出现在名为“操作”的最后列中

这些必须作为注解添加到 Grid 注解中

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Dtc\GridBundle\Annotation as Grid;

/**
 * Class User
 * @Grid\Grid(actions={@Grid\ShowAction(), @Grid\DeleteAction(), @Grid\Action(label="Custom",buttonClass="btn-info",onclick="alert('custom-action')")})
 * @ORM\Entity
 * @package App\Entity
 */
class User {
    //...
}

更自定义的路由

/**
 * @Route("/users", name="app_grid_users")
 */
public function usersAction(Request $request) {
    $renderer = $this->get('dtc_grid.renderer.factory')->create('datatables');
    $gridSource = $this->get('dtc_grid.manager.source')->get('App:User');
    $renderer->bind($gridSource);
    return $this->render('@DtcGrid/Page/datatables.html.twig', $renderer->getParams());
}

更改渲染器

/**
 * @Route("/users_table", name="app_grid_users_table")
 */
public function usersAction(Request $request) {
    $renderer = $this->get('dtc_grid.renderer.factory')->create('table');
    $gridSource = $this->get('dtc_grid.manager.source')->get('App:User');
    $renderer->bind($gridSource);
    return $this->render('@DtcGrid/Page/datatables.html.twig', $renderer->getParams());
}

自定义列

在 Dtc\GridBundle\Annotation 中有一个 @Column 注解,您可以将它放置在您想要显示的每一列上。然后您可以根据需要指定自定义标签和/或排序性。如果没有 @GridColumn 注解,它将默认显示所有列。

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Dtc\GridBundle\Annotation as Grid;

/**
 * Class User
 * @Grid\Grid
 * @ORM\Entity
 * @package App\Entity
 */
class User {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @Grid\Column(searchable=true)
     * @ORM\Column(type="string")
     */
    protected $firstName;

    /**
     * @Grid\Column(label="Last", sortable=true, searchable=true)
     * @ORM\Column(type="string")
     */
    protected $lastName;

自定义 jQuery、Purl、DataTables

可以在 config.yml 中自定义 jQuery、Purl 和 DataTables 的版本

dtc_grid:
    theme: # theme defaults to bootstrap 3
        css:
            - 'path_or_url_to/bootstrap_or_any_other.css'
            - 'etc. as necessary'
        js:
            - 'path_or_url_to/any_javascript_needed_for_theme.js'
            - 'etc. as necessary'            
    purl: 'path_or_url_to/purl.js' # presently defaults to v2.3.1 hosted on cdnjs
    jquery: # presently defaults to 3.2.1 hosted on jquery's code.jquery.com cdn
        url: 'path_or_url_to/jquery.js'
        integrity: ~ # or an integrity for the file
        crossorigin: ~ # or what goes in the crossorigin section of the script tag
    datatables: # presently defaults to 1.10.16 hosted on cdn.datatables.net
        css:
            - 'path_or_url_to/datatables.css'
            - 'path_or_url_to/any_other_needed.css'
        js:
            - 'path_or_url_to/datatables.js'
            - 'path_or_url_to/datatables_theme.js'
            - 'etc. as necessary'

JQ Grid

要使用 JQ Grid,您需要指定绝对 URL 或相对于绝对路径的 JQGrid 文件。

由于 JQ Grid 的许可证与此捆绑包不同,因此没有提供默认值。

# config.yml
dtc_grid:
    jq_grid:
        css:
            - 'path_or_url_to/prettify.css'
            - 'path_or_url_to/ui.jqgrid-bootstrap.css'
        js:
            - 'path_or_url_to/grid.locale-en.js'
            - 'path_or_url_to/jquery.jqGrid.js'
    /**
     * @Route("/users_table", name="app_grid_users_table")
     */
    public function usersAction(Request $request) {
        $renderer = $this->get('dtc_grid.renderer.factory')->create('jq_grid');
        $gridSource = $this->get('dtc_grid.manager.source')->get('App:User');
        $renderer->bind($gridSource);
        return $this->render('@DtcGrid/Page/datatables.html.twig', $renderer->getParams());
    }

自定义 Bootstrap

    # config.yml
    dtc_grid:
        bootstrap:
            css: path_or_url_to_bootstrap.css
            js: path_or_url_to_bootstrap.js

同一页面上的多个网格

如果要在同一页面上渲染多个网格,则需要使用 RendererFactory。

当前支持三种渲染器类型

  • datatables
  • jq_grid
  • table
    /**
     * List jobs in system by default.
     *
     * @Route("/jobs/")
     */
    public function jobsAction()
    {
        $rendererFactory = $this->get('dtc_grid.renderer.factory');
        $renderer = $rendererFactory->create('datatables');
        $gridSource = $this->get('dtc_grid.manager.source')->get('Dtc\\QueueBundle\\Documents\\Job');
        $renderer->bind($gridSource);
        $params = $renderer->getParams();

        $renderer2 = $rendererFactory->create('datatables');
        $gridSource2 = $this->get('dtc_grid.manager.source')->get('Dtc\\QueueBundle\\Documents\\JobArchive');
        $renderer2->bind($gridSource2);
        $params2 = $renderer2->getParams();

        $params['archive_grid'] = $params2['dtc_grid'];
        return $this->render('@DtcQueue/Queue/jobs.html.twig', $params);
    }

同一页面上渲染多个网格的Twig文件

jobs.html.twig

{% extends "DtcGridBundle:Page:datatables.html.twig" %}

{% block grid %}
    <h3>Live Jobs</h3>
    {{ dtc_grid.render | raw }}
    <h3>Archived Jobs</h3>
    {{ archive_grid.render | raw }}
{% endblock %}

您甚至可以在同一页面上渲染多种类型的网格

    /**
     * List jobs in system by default.
     *
     * @Route("/jobs/")
     */
    public function jobsAction()
    {
        $rendererFactory = $this->get('dtc_grid.renderer.factory');
        $renderer = $rendererFactory->create('jq_grid');  // NOTE THE DIFFERENT GRID TYPE
        $gridSource = $this->get('dtc_grid.manager.source')->get('Dtc\\QueueBundle\\Documents\\Job');
        $renderer->bind($gridSource);
        $params = $renderer->getParams();

        $renderer2 = $rendererFactory->create('datatables');
        $gridSource2 = $this->get('dtc_grid.manager.source')->get('Dtc\\QueueBundle\\Documents\\JobArchive');
        $renderer2->bind($gridSource2);
        $params2 = $renderer2->getParams();

        $params['archive_grid'] = $params2['dtc_grid'];
        return $this->render('@DtcQueue/Queue/jobs.html.twig', $params);
    }

jobs.html.twig(由于需要包含两种网格类型的样式和JavaScript,因此稍微复杂一些,但如果使用“table”类型渲染器,则不必这样做,因为它的CSS和JavaScript与“datatables”渲染器重叠)

{% extends '@DtcGrid/layout_base_jquery.html.twig' %}

{% block dtc_grid_stylesheets %}
    {% for stylesheet in dtc_grid_jq_grid_css %}
        <link rel="stylesheet" href="{{ stylesheet }}" />
    {% endfor %}
    {% for stylesheet in dtc_grid_datatables_css %}
        <link rel="stylesheet" href="{{ stylesheet }}" />
    {% endfor %}
{% endblock %}

{% block dtc_grid_javascripts %}
    {{ parent() }}
    {% for javascript in dtc_grid_jq_grid_js %}
        <script type="text/javascript" src="{{ javascript }}"></script>
    {% endfor %}    
    {% for javascript in dtc_grid_datatables_js %}
        <script src="{{ javascript }}"></script>
    {% endfor %}
{% endblock %}

{% block grid %}
    <h3>Live Jobs</h3>
    {{ dtc_grid.render | raw }}
    <h3>Archived Jobs</h3>
    {{ archive_grid.render | raw }}
{% endblock %}

自定义/嵌入网格

要自定义网格的CSS/JavaScript或将其嵌入到现有页面中,请参考以下示例

/**
 * @Route("/users_custom", name="app_grid_users_custom")
 */
public function usersCustomAction(Request $request) {
    // other setup, etc.
    // Assuming you have a variable called "$params"

    $renderer = $this->get('dtc_grid.renderer.factory')->create('datatables'); // or whichever renderer you want to use

    $gridSource = $this->get('dtc_grid.manager.source')->get('App:User');
    $renderer->bind($gridSource);

    $renderer->getParams($params); // This will add the grid-specific params (mainly 'grid', and the bootstrap urls)
    
    // Alternatively you can do
    // $dataGridParams = $renderer->getParams();
    // $myParams['my_grid'] = $dataGridParams['dtc_grid'];

    // render your page
    return $this->render('@App/Something/somepage.html.twig', $params);
}

datatables Twig示例

<html>
<head>
    {% block stylesheets %}
        {% for stylesheet in dtc_grid_theme_css %}
            <link rel="stylesheet" href="{{ stylesheet }}">
        {% endfor %}
    {% endblock %}

    {% block dtc_grid_stylesheets %}
        {% for stylesheet in dtc_grid_datatables_css %}
            <link rel="stylesheet" href="{{ stylesheet }}" />
        {% endfor %}
        {% for stylesheet in dtc_grid_local_css %}
           <link rel="stylesheet" href="{{ app.request.baseUrl }}{{ stylesheet }}" />
        {% endfor %}
    {% endblock %}
    
    {% block dtc_grid_javascripts %}
        <script src="{{ dtc_grid_jquery.url }}"
            {% if dtc_grid_jquery.integrity is not empty  %} integrity="{{ dtc_grid_jquery.integrity }}"{% endif %}
            {% if dtc_grid_jquery.crossorigin is not empty  %} crossorigin="{{ dtc_grid_jquery.crossorigin }}"{% endif %}>
        </script>
        <script src="{{ dtc_grid_purl }}"></script>
        {% for javascript in dtc_grid_datatables_js %}
            <script src="{{ javascript }}"></script>
        {% endfor %}
    {% endblock %}
    
    {% block javascripts %}
        {% for javascript in dtc_grid_theme_js %}
            <script src="{{ javascript }}"></script>
        {% endfor %}
        {% for javascript in dtc_grid_local_js %}
            <script src="{{ app.request.baseUrl }}{{ javascript }}"></script>
        {% endfor %}
    {% endblock javascripts %}
</head>
<body>

<!-- .... -->
{# This is the most important part - 'dtc_grid.render' should be 'dtc_grid.render' or 'my_grid.render', or whatever you called it if you change the parameter's name #}
{{ dtc_grid.render | raw }}

<!-- ... -->
</body>
</html>

JQGrid Twig示例

<html>
<head>
    {% block stylesheets %}
        {% for stylesheet in dtc_grid_theme_css %}
            <link rel="stylesheet" href="{{ stylesheet }}">
        {% endfor %}
        {% for stylesheet in dtc_grid_local_css %}
           <link rel="stylesheet" href="{{ app.request.baseUrl }}{{ stylesheet }}" />
        {% endfor %}
    {% endblock %}

    {% block dtc_grid_stylesheets %}
        {% for stylesheet in dtc_grid_jq_grid_css %}
            <link rel="stylesheet" href="{{ stylesheet }}" />
        {% endfor %}
    {% endblock %}
    
    {% block dtc_grid_javascripts %}
        <script src="{{ dtc_grid_jquery.url }}"
            {% if dtc_grid_jquery.integrity is not empty  %} integrity="{{ dtc_grid_jquery.integrity }}"{% endif %}
            {% if dtc_grid_jquery.crossorigin is not empty  %} crossorigin="{{ dtc_grid_jquery.crossorigin }}"{% endif %}>
        </script>
        <script src="{{ dtc_grid_purl }}"></script>
        {% for javascript in dtc_grid_jq_grid_js %}
            <script type="text/javascript" src="{{ javascript }}"></script>
        {% endfor %}    
    {% endblock %}
    
    {% block javascripts %}
        {% for javascript in dtc_grid_theme_js %}
            <script src="{{ javascript }}"></script>
        {% endfor %}
        {% for javascript in dtc_grid_local_js %}
            <script src="{{ app.request.baseUrl }}{{ javascript }}"></script>
        {% endfor %}
    {% endblock javascripts %}
</head>
<body>

<!-- .... -->
{# This is the most important part - 'dtc_grid.render' should be 'dtc_grid.render' or 'my_grid.render', or whatever you called it if you change the parameter's name #}
{{ dtc_grid.render | raw }}

<!-- ... -->
</body>
</html>

Table Twig示例

<html>
<head>
    {% block stylesheets %}
        {% for stylesheet in dtc_grid_theme_css %}
            <link rel="stylesheet" href="{{ stylesheet }}">
        {% endfor %}
        {% for stylesheet in dtc_grid_local_css %}
           <link rel="stylesheet" href="{{ app.request.baseUrl }}{{ stylesheet }}" />
        {% endfor %}
    {% endblock %}

    {% block javascripts %}
        {% for javascript in dtc_grid_theme_js %}
            <script src="{{ javascript }}"></script>
        {% endfor %}
        {% for javascript in dtc_grid_local_js %}
            <script src="{{ app.request.baseUrl }}{{ javascript }}"></script>
        {% endfor %}
    {% endblock javascripts %}
</head>
<body>

<!-- .... -->
{# This is the most important part - 'dtc_grid.render' should be 'dtc_grid.render' or 'my_grid.render', or whatever you called it if you change the parameter's name #}
{{ dtc_grid.render | raw }}

<!-- ... -->
</body>
</html>

文档

还有额外的(目前有些过时的)文档存储在 Resources/doc/

过时

以前您需要使用“Generator”来创建grid.source服务,但现在不再需要了,但是有关如何使用它的文档仍然可在Resources/doc/区域找到。

许可证

此软件包受MIT许可证保护(请参阅Resources/meta/LICENSE下的LICENSE文件)。

致谢

最初由 @dtee 编写,由 @mmucklo 维护