Important

You are browsing the documentation for version 4.1 of OroCommerce, OroCRM and OroPlatform, which is no longer maintained. Read version 5.1 (the latest LTS version) of the Oro documentation to get up-to-date information.

See our Release Process documentation for more information on the currently supported and upcoming releases.

Backend Datagrid

Datagrid is a table oriented representation of the data from a datasource. It is configured in a YAML file placed in the Resources/config/oro folder of your bundle and called datagrids.yml. This file should contain the root node datagrids and each grid configuration must be placed under it.

Getting Started

Configuration File

To define your own datagrid, create a configuration file as described above. Next, choose the identifier of your future grid and declare it by adding an associative array with the identifier as the key.

For example:

1 datagrids:
2     acme-demo-datagrid:     # grid identifier
3         ...                 # configuration will be here

Datasource

The next step is to configure datasource, which is a similar array under the source node. Choose datasource type and properly configure it. For further details, check the datasources section.

For example:

1 datagrids:
2     acme-demo-datagrid:
3         source:
4             type: orm  # datasource type
5             query:
6                 ....   # some query configuration

Datasource as Service

Other than the query yaml-oriented provider, ORM datasource supports an alternative query_builder service-oriented provider. You use any arbitrary method that returns a valid Doctrine\ORM\QueryBuilder instance.

 1 // @acme_demo.user.repository
 2 public class UserRepository
 3 {
 4     // ....
 5
 6     /**
 7     * @return Doctrine\ORM\QueryBuilder
 8     */
 9     public function getUsersQb()
10     {
11         return $this->em->createQueryBuilder()
12             ->from('AcmeDemoBundle:User', 'u')
13             ->select('u')
14             // ->where(...)
15             // ->join(...)
16             // ->orderBy(...)
17         ;
18     }
19 }

In the datagrid configuration, provide the service and method name:

1 datagrids:
2     acme-demo-datagrid:
3         source:
4             type: orm  # datasource type
5             query_builder: "@acme_demo.user.repository->getUsersQb"

Parameters Binding

If datasource supports parameters binding, you can specify an additional option bind_parameters. For example

 1 datagrids:
 2     acme-demo-datagrid:
 3         source:
 4             type: orm
 5             query:
 6                 select:
 7                     - u
 8                 from:
 9                     { table: AcmeDemoBundle:User, alias:u }
10             where:
11                 and:
12                     - u.group = :group_id
13             bind_parameters:
14                 group_id: groupId

Parameters binding is also supported while using the query_builder notation for the ORM data source. Each binding calls ->setParameter('group_id', group_id) automatically on the provided builder.

See more in the parameters binding section.

Columns and Properties

Next step is columns definition. It is an array as well as other parts of grid configuration. The root node for columns is columns, the definition key should be a unique column identifier, the value is an array of the column configuration. The same for properties, but the root node is properties.

A property is something similar to a column but without frontend representation. Properties can be used to pass additional data generated for each row, for example URLs of row actions.

Note

The column identifier is used for a suggestion, so best practice is to use an identifier similar to the data identifier (e.g., a field name in DQL).

Note

A row identifier property is usually added for correct work, but for simple grids it is excessive.

The configuration format is different depending on the column type, but there is a list of keys shared between all types.

  • type - backend formatter type (field by default)

  • label - column title (translated on backend, translation should be placed in “messages” domain)

  • frontend_type - frontend formatters that process the column value (string by default)

  • editable - is a column editable on frontend (false by default)

  • data_name - data identifier (column name suggested by default)

  • renderable - whether the column should be rendered (true by default)

  • order - the number of column’s position, allows to change order of the columns over Datagrid Settings and save it in Grid View (by default it is not defined and the columns are rendered in the order in which they are declared in the configuration)

  • required - if it is true, the column cannot be hidden over Datagrid Settings (false by default)

  • manageable - if it is false, the column does not appear in Datagrid Settings (true by default)

  • shortenableLabel - could column label be abbreviated or shortened with ellipsis (true - by default)

For a detailed explanation, see the section on formatters.

So lets define few columns:

 1 datagrids:
 2     acme-demo-datagrid:
 3         source:
 4             type: orm
 5             query:
 6                 select: [ o.firstName, o.lastName, o.age ]
 7                 from:
 8                     - { table: AcmeDemoBundle:Entity, alias: o } #defining table class using FQCN
 9 #                    - { table: '%acme_demo.entity.entity_name.class%', alias: o } #defining table class using parameter
10         columns:
11             firstName:                                   # data identifier will be taken from column name
12                 label: acme.demo.grid.columns.firstName  # translation string
13             lastName:
14                 label: acme.demo.grid.columns.firstName  # translation string
15             age:
16                 label: acme.demo.grid.columns.age        # translation string
17                 frontend_type: number                    # needed for correct l10n (e.g. thousand, decimal separators etc)

Sorting

After that you may want to make your columns sortable. Sorting configuration should be placed under the sorters node. In basic sorter implementation, the configuration takes the columns and default keys. It is an array of column names where the value is sorter configuration. There is one required value data_name that is responsible for knowledge on which datagrid should do sorting.

Lets make all columns sortable:

 1 datagrids:
 2     acme-demo-datagrid:
 3         ...                                 # definition from previous examples
 4         sorters:
 5             columns:
 6                 firstName:
 7                     data_name: o.firstName
 8                 lastName:
 9                     data_name: o.lastName
10                 age:
11                     data_name: o.age
12             default:
13                 lastName: DESC              # Default sorting, allowed values ASC|DESC

For detailed explanation, see the section on sorters.

Final Step

Final step for this tutorial is to add grid to template. There is a predefined macro for grid rendering, that is defined in ` OroDataGridBundle::macros.html.twig` and can be imported by the following call {% import 'OroDataGridBundle::macros.html.twig' as dataGrid %} . Macro’s name is renderGrid, it takes 2 arguments: grid name, route parameters(used for advanced query building). So for displaying our grid we have to add following code to template:

1 {% import 'OroDataGridBundle::macros.html.twig' as dataGrid %}
2 {% block content %}
3      {{ dataGrid.renderGrid('acme-demo-datagrid') }}
4 {% endblock %}

Note

If your template extends the OroUIBundle:actions:index.html.twig template, macros will be already imported and you only have to set the gridName variable to get the grid rendered

Advanced Configuration

Actions, mass actions, toolbar, pagers, grid views and other functionality are explained on advanced grid configuration page or you can check configuration reference.

Extendability

Behavior Customization

In order to customize the datagrid (e.g., dynamically added columns, custom actions, add additional data, etc.), you can listen to one of the events dispatched in the datagrid component. More information on events, including their full list, is available in the section on events.

Extending

The grid can be extended in several ways:

  • create a custom datasource, if needed (e.g., already implemented SearchDatasource for working with search engine)

  • create a custom extension

  • create some addons to the already registered extensions (e.g., a specific backend formatter)

  • change the base datagrid or the base acceptor class (they are passed to the builder as DIC parameters)

Related Articles