Skip to content

Instantly share code, notes, and snippets.

@hiro-iFactory
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiro-iFactory/ac273c8a043a8f82d878 to your computer and use it in GitHub Desktop.
Save hiro-iFactory/ac273c8a043a8f82d878 to your computer and use it in GitHub Desktop.
How to send multiple parameters to Oro Datagrid
<?php
// src/Acme/Bundle/AcmeBundle/EventListener/BaseOrmRelationDatagridListener.php
namespace Acme/Bundle/AcmeBundle\EventListener;
use Doctrine\ORM\QueryBuilder;
use Oro\Bundle\DataGridBundle\Datagrid\ParameterBag;
use Oro\Bundle\DataGridBundle\Datasource\Orm\OrmDatasource;
use Oro\Bundle\DataGridBundle\Event\BuildAfter;
use Oro\Bundle\DataGridBundle\EventListener\BaseOrmRelationDatagridListener as BaseClass;
/**
* Class BaseRelationDatagridListener
* Event listener should be applied when entities relation managed via datagrid
*/
class BaseOrmRelationDatagridListener extends BaseClass
{
/**
* Add filters to where clause
* Base query should looks as following:
* (CASE WHEN (:relationParamName IS NOT NULL) THEN
* CASE WHEN (:relationParamName
* MEMBER OF alias.relationField OR alias.id IN (:data_in)) AND alias.id NOT IN (:data_not_in)
* THEN true ELSE false END
* ELSE
* CASE WHEN alias.id IN (:data_in) AND alias.id NOT IN (:data_not_in)
* THEN true ELSE false END
* END) as relationColumnName
*
* @param BuildAfter $event
*/
public function onBuildAfter(BuildAfter $event)
{
$datagrid = $event->getDatagrid();
$datasource = $datagrid->getDatasource();
$parameters = $datagrid->getParameters();
if ($datasource instanceof OrmDatasource) {
/** @var QueryBuilder $query */
$queryBuilder = $datasource->getQueryBuilder();
$additionalParams = $parameters->get(ParameterBag::ADDITIONAL_PARAMETERS, []);
if (isset($additionalParams[self::GRID_PARAM_DATA_IN])) {
$dataIn = $additionalParams[self::GRID_PARAM_DATA_IN];
} else {
$dataIn = [0];
}
if (isset($additionalParams[self::GRID_PARAM_DATA_NOT_IN])) {
$dataOut = $additionalParams[self::GRID_PARAM_DATA_NOT_IN];
} else {
$dataOut = [0];
}
$queryParameters = array(
'data_in' => $dataIn,
'data_not_in' => $dataOut,
);
/**
* The difference from the parent class (BaseClass) is that
* $this->paramName is expected as Array in this Listener Class
*/
foreach ($this->paramName as $paramName) {
$queryParameters[$paramName] = $parameters->get($paramName);
}
if (!$this->isEditMode) {
unset($queryParameters['data_in'], $queryParameters['data_not_in']);
}
$queryBuilder->setParameters($queryParameters);
}
}
}
// src/Acme/Bundle/AcmeBundle/Resources/public/js/common.js
/*
You need to provide custom Datagrid listener class prior to use this functionality
(BaseOrmRelationDatagridListener.php)
You need to run the following commands at Symfony root directory to include this file to web/bundles/acme/js:
php app/console assets:install; php app/console assetic:dump
Usage:
var query = {
id: myId,
param_1: 'value 1',
param_2: myValue / 100
};
$('#grid-acme-grid').acmeRefreshGrid(query);
*/
define([
'jquery',
'oroui/js/mediator'
],
function(
$,
mediator
) {
$.fn.extend({
/**
* Generates URL for Datagrid
*
* @param string gridId
* @param object query {key1: value1, key2: value2, ...}
* @returns string
*/
acmeGenerateGridUrl: function(gridName, query) {
var url = '/datagrid/' + gridName + '?';
var queryNew = [];
$.each(query, function(key, value) {
// The variant type of "value" for numeric value like "0.09", is not String
// which does not have replace() and gets error if you just apply.
// Therefore, it is casting by adding "" before applying the method.
value = ('' + value).replace(/\s/, '+');
queryNew.push(encodeURIComponent(gridName + '[' + key + ']') + '=' + value);
});
url += queryNew.join('&');
return url;
},
/**
* Refresh Oro Datagrid
*
* @param object query {key1: value1, key2: value2, ...}
*/
acmeRefreshGrid: function(query) {
if (this.data('datagrid')) {
var gridName = this.data('metadata').options.gridName;
var url = this.acmeGenerateGridUrl(gridName, query);
this.data('datagrid').collection.url = url;
/**
* Refresh the datagrid
*
* https://github.com/orocrm/platform/blob/master/src/Oro/Bundle/DataGridBundle/Resources/doc/frontend/datagrid.md
* http://thejacklawson.com/Mediator.js/
*/
mediator.trigger('datagrid:doRefresh:' + gridName);
}
}
});
return $;
});
# src/Acme/Bundle/AcmeBundle/Resources/config/datagrid.yml
datagrid:
acme-grid:
extended_entity_name: %acme.entity.class%
source:
type: orm
acl_resource: acme_example_view
query:
select:
- e.id
- e.name
- :param_1 as Label
- e.value * :param_2 as Value
from:
- { table: %acme.entity.class%, alias: e }
where:
and:
- e.id = :id
# Omitting
# src/Acme/Bundle/AcmeBundle/Resources/config/services.yml
parameters:
acme.entity.class: Acme\Bundle\AcmeBundle\Entity\Example
acme.datagrid_event_listener.orm_relation.class: Acme\Bundle\AcmeBundle\EventListener\BaseOrmRelationDatagridListener
services:
#
# Enable to send the parameter to the grid
#
acme.event_listener.grid_listener:
class: %acme.datagrid_event_listener.orm_relation.class%
arguments: [[id, param_1, param_2], false]
tags:
- { name: kernel.event_listener, event: oro_datagrid.datagrid.build.after.acme-grid, method: onBuildAfter }
// src/Acme/Bundle/AcmeBundle/Resources/views/Default/update.html.twig
{% extends 'OroUIBundle:actions:update.html.twig' %}
{% import 'OroDataGridBundle::macros.html.twig' as dataGrid %}
{% form_theme form with 'OroFormBundle:Form:fields.html.twig' %}
{% oro_title_set({params : {"%acme.entity.name%": entity.id} }) %}
{% set formAction = form.vars.value.id ? path('acme_update', { 'id': form.vars.value.id }) : path('acme_create') %}
{# Omitting #}
{% block content_data %}
{% set id = 'acme-detail' %}
{% set dataBlocks = dataBlocks|merge([{
'title': 'acme.quotes.tab.example'|trans,
'subblocks':
[
{
'title': null,
'data': [
form_row(form.list),
form_row(form.ratio),
dataGrid.renderGrid(
'acme-grid',
{
'id': entity.id,
'param_1': entity.list|default(''),
'param_2': entity.ratio|default(0)
},
{'cssClass': 'inner-grid'}
),
]
}
]
}]) %}
{% set data =
{
'formErrors': form_errors(form)? form_errors(form) : null,
'dataBlocks': dataBlocks,
}
%}
{{ parent() }}
<script type="text/javascript">
require(['acme/js/common'],
function($) {
// Refresh Datagrid
$('#list').bind('change', function() {
var query = {
id: '{{ entity.id }}',
param_1: $('#list').val(),
param_2: $('#ratio').val()
};
$('#grid-acme-grid').acmeRefreshGrid(query);
});
});
</script>
{% endblock content_data %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment