Grid in OroCRM is a very convenient way to display information about all or few records of an entity. Default OroCRM has a lot of grids for different entities. OroCRM developers provided a useful and easy way to create grids for a custom entity or display some specific information for default entities.
For example, let’s take a look at the users grid:
As you can also see, it is a simple table with rows and columns that contain information about users. Also, the grid includes a list of filters, pagination and some actions. Moreover, each row has few functionalities to view, edit or delete data there. The standard grid control section located at the top includes all those elements. If more detailed:
- Export button – allows to export grid content in CSV format.
- Pagination control – provides information about a grid page itself, records in the grid and total number of pages. Number of pages in the grid depends on its configuration, this parameters can be set in System -> Configuration -> Display settings -> Data Grid settings.
- Grid content controls – allow to change the number of records displayed per page using the View per Page control, refresh grid contents, reset the grid to its default view.
- Filters – are useful when you need to pick up the records that you need from entire data. The filters are located above the grid controls.
We have already reviewed the frontend part of the grid, and now let’s move to its backend side. We’ve took the Users grid as an example. Pay attention that each grid should be configured in the parameters file. This file is located in …Bundle/Resources/config folder, it is called datagrid.yml and has the following structure:
datagrid: users-grid: extended_entity_name: %oro_user.entity.class% options: entityHint: user entity_pagination: true acl_resource: oro_user_user_view source: type: orm query: select: - u.id - u.username - u.email - u.firstName - u.lastName - u.createdAt - u.updatedAt - u.enabled from: - { table: %oro_user.entity.class%, alias: u } inline_editing: enable: true columns: firstName: label: oro.user.first_name.label lastName: label: oro.user.last_name.label email: label: oro.user.email.label username: label: oro.user.username.label enabled: label: oro.user.enabled.label frontend_type: select choices: - Inactive - Active createdAt: label: oro.ui.created_at frontend_type: datetime updatedAt: label: oro.ui.updated_at frontend_type: datetime properties: id: ~ update_link: type: url route: oro_user_update params: - id view_link: type: url route: oro_user_view params: - id delete_link: type: url route: oro_api_delete_user params: - id sorters: columns: username: data_name: u.username email: data_name: u.email firstName: data_name: u.firstName lastName: data_name: u.lastName createdAt: data_name: u.createdAt updatedAt: data_name: u.updatedAt enabled: data_name: u.enabled default: username: %oro_datagrid.extension.orm_sorter.class%::DIRECTION_ASC filters: columns: firstName: type: string data_name: u.firstName lastName: type: string data_name: u.lastName email: type: string data_name: u.email username: type: string data_name: u.username enabled: type: choice data_name: u.enabled options: field_options: choices: 'false': Inactive 'true': Active createdAt: type: datetime data_name: u.createdAt updatedAt: type: datetime data_name: u.updatedAt actions: view: type: navigate label: oro.grid.action.view link: view_link icon: eye-open acl_resource: oro_user_user_view rowAction: true update: type: navigate label: oro.grid.action.update link: update_link icon: edit acl_resource: oro_user_user_update delete: type: delete label: oro.grid.action.delete link: delete_link icon: trash acl_resource: oro_user_user_delete
Now let’s check it more detailed.
Name (Identifier)
The first part of a grid is a name. Previously mentioned users grid has “users-grid” name, it is a unique identifier for the grid in application.
Extends
Almost every grid may be extended: we can use data from a parent grid with necessary adjustments and additions. For that purpose use “extends” configuration node:
user-cases-grid: extends: cases-grid source: query: where: and: - (assignedTo.id = :id OR owner.id = :id) bind_parameters: - id options: entity_pagination: false
The “user-cases-grid” extends the “cases-grid” and then changes the “source” node, all filters, sorters from parent grid.
Source
There is a specific query to get data from any entity. The grid can receive the data from one entity or join few entities. For example, the users grid uses only one entity:
source: type: orm query: select: - u.id - u.username - u.email - u.firstName - u.lastName - u.createdAt - u.updatedAt - u.enabled from: - { table: %oro_user.entity.class%, alias: u }
When, for example, the business unit’s grid additionally uses owner’s entity:
source: acl_resource: oro_business_unit_view type: orm query: select: - u.id - u.name - u.email - u.phone - u.createdAt - owner.name as ownerName from: - { table: OroOrganizationBundle:BusinessUnit, alias: u } join: left: owner: join: u.owner alias: owner
Columns
This part of a grid setting describes the columns and type of data that are shown in the grid. There should be some unique column identifier and type of data. The default type is a string, check it below:
columns: firstName: label: oro.user.first_name.label lastName: label: oro.user.last_name.label email: label: oro.user.email.label username: label: oro.user.username.label enabled: label: oro.user.enabled.label frontend_type: select choices: - Inactive - Active createdAt: label: oro.ui.created_at frontend_type: datetime updatedAt: label: oro.ui.updated_at frontend_type: datetime
Configuration format of the columns is different, depending on the data type. Here is a list of parameters for all types:
- type – backend formatter type (default value: field)
- label – column title (translated on backend, translation should be placed in “messages” domain)
- frontend_type – frontend formatters that process the column value (default value: string)
- editable – is a column editable on frontend (default value: false)
- renderable – should a column be rendered? (default value: true)
- data_name – data identifier (column name suggested by default)
Properties
It is a unique identifier for some value like link, template etc. Property is similar to column, but it does not have a frontend representation.
properties: id: ~ update_link: type: url route: oro_user_update params: - id view_link: type: url route: oro_user_view params: - id delete_link: type: url route: oro_api_delete_user params: - id
Sorters
It is used for making the grid’s columns sortable.
sorters: columns: username: data_name: u.username email: data_name: u.email firstName: data_name: u.firstName lastName: data_name: u.lastName createdAt: data_name: u.createdAt updatedAt: data_name: u.updatedAt enabled: data_name: u.enabled default: username: %oro_datagrid.extension.orm_sorter.class%::DIRECTION_ASC
Filters
In this node we describe the list of grid’s filters and types.
filters: columns: firstName: type: string data_name: u.firstName lastName: type: string data_name: u.lastName email: type: string data_name: u.email username: type: string data_name: u.username enabled: type: choice data_name: u.enabled options: field_options: choices: 'false': Inactive 'true': Active createdAt: type: datetime data_name: u.createdAt updatedAt: type: datetime data_name: u.updatedAt
Actions
It describes the list of row’s actions. In our users grid example, we can see that actions use the parameters that we’ve described in the parameters node (view_link, update_link, delete_link).
actions: view: type: navigate label: oro.grid.action.view link: view_link icon: eye-open acl_resource: oro_user_user_view rowAction: true update: type: navigate label: oro.grid.action.update link: update_link icon: edit acl_resource: oro_user_user_update delete: type: delete label: oro.grid.action.delete link: delete_link icon: trash acl_resource: oro_user_user_delete
On the frontend part, the grid is displayed by the specific macros. We only need to set name (identifier) of this grid.
{% import 'OroDataGridBundle::macros.html.twig' as dataGrid %} {% block content %} {{ dataGrid.renderGrid(users-grid) }} {% endblock %}
Also, there is a possibility to pass the additional grid query parameters. Let’s check the standard “user-cases-grid”:
{{ dataGrid.renderGrid('user-cases-grid', {id: entity.id}) }}
And its backend part:
user-cases-grid: extends: cases-grid source: query: where: and: - (assignedTo.id = :id OR owner.id = :id) bind_parameters: - id options: entity_pagination: false
It uses a specific “bind_parameters” node for parameters binding.
In case if names of parameters in the grid and query do not match, you can pass an associative array of parameters where the key is the name of parameter in the query and a value is the name of parameter:
query: where: and: - (assignedTo.id = :user_id OR owner.id = :user_id) bind_parameters: user_id: id
As you can see, the functionality of OroDataGridBundle is really powerful. We do not need to write a lot of code, just customize columns, add actions, sorters and different type of filters. It makes the development process more productive and handy.