Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

DataGrid bundle documentation

Version: 1.2.0

The DataGrid bundle allow to display a datagrid into twig template.

Installation

Register the bundle into app/appKernel.php

// app/AppKernel.phpclass AppKernel extends Kernel
{
publicfunctionregisterBundles()
{
$bundles = array(
[...]
newCscfa\Bundle\DataGridBundle\CscfaDataGridBundle(),
);
[...]
}
}

Create you'r first datagrid

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridContainer;

The datagrid system use the DataGridContainer class to define the datagrid informations.

Basically, this class is instanciate with a set of data to display, the access method to get the specifically data from each elements, the headers to display and the elements type.

By 'element', we understand the row data container. This element can be an array or an object. By default, the container use each element as array. If you give an array of object, as a doctrine findAll result, you will must specify it by passing DataGridContainer::TYPE_OBJECT as fourth argument of the constructor.

To display data, you'll must specify the access methods to it. By passing an array of string you can inform on the access method of each elements data. If the elements are array, the access method will be an array of key to display. If the elements are objects, the access method will be the getter methods of the objects.

The header argument is an array of string that inform on the header of each column.

// Asume this code is into a controller$datas = array(array("element 1.1", "element 1.2"), array("element 2.1", "element 2.2"));
$dataGrid = newDataGridContainer($datas, array(0, 1), array("head1", "head2"), DataGridContainer::TYPE_ARRAY);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And into the twig template :

{# in your template file #}
{{ renderDatagrid(data) }}

No one of the arguments are required to instanciate the DataGridContainer class and empty container does not generate exception.

You can instanciate a datagrid with this code :

// Asume this code is into a controller$dataGrid = newDataGridContainer();
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

And define each arguments with this :

// Asume this code is into a controller/* * Note we use here the result of a doctrine request * And we specify the the type is object. */$manager = $this->getDoctrine()->getManager();
$repository = $manager->getRepository("Acme\Bundle\AcmeBundle\Entity\Miscellaneous");
$miscs = $repository->findAll();
$dataGrid = newDataGridContainer();
$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getName", "getId");
$dataGrid->setHeader("name", "identity");
$dataGrid->setType(DataGridContainer::TYPE_OBJECT);
$this->render("AcmeBundle:Default:index.html.twig", array("data"=>$dataGrid));

Since version 1.2.0, the DataGridContainer allow to use chained access method by using a '.' delimiter bteween each access method.

//This access to $miscs->getBag()->getName()$dataGrid->setContainer($miscs);
$dataGrid->setAccessMethods("getBag.getName");

Advanced use with callbacks

// in php fileuseCscfa\Bundle\DataGridBundle\Objects\DataGridStepper;

The datagrid can use callbacks that will be calls by a DataGridStepper into the rendering step by step. Some of this callbacks already exists into the default templates. We can use :

Callback namedescription
onGridStartThis callback is called before the datagrid
onGridStopThis callback is called after the datagrid
onGridThis callback is called to render the main datagrid html opening tag attributes, after the tag name and before the tag end
onGridPrependThis callback is called after the main datagrid html opening tag
onGridAppendThis callback is called before the main datagrid html closing tag
onHeadStartThis callback is called before the header html opening tag
onHeadStopThis callback is called after the header html closing tag
onHeadThis callback is called to render the header html opening tag attributes
onHeadPrependThis callback is called after the header html opening tag
onHeadAppendThis callback is called before the header html closing tag
onHeadElementStartThis callback is called before each header element html opening tag
onHeadElementStopThis callback is called after each header element html closing tag
onHeadElementThis callback is called to render each header element html opening tag attributes
onHeadElementPrependThis callback is called after each header element html opening tag
onHeadElementAppendThis callback is called before each header html closing tag
onBodyStartThis callback is called before the body html opening tag
onBodyStopThis callback is called after the body html closing tag
onBodyThis callback is called to render the body html opening tag attributes
onBodyPrependThis callback is called after the body html opening tag
onBodyAppendThis callback is called before the body html closing tag
onRowStartThis callback is called before each row html opening tag
onRowStopThis callback is called after each row html closing tag
onRowThis callback is called to render each row html opening tag attributes
onRowPrependThis callback is called after each row html opening tag
onRowAppendThis callback is called before each row html closing tag
onElementStartThis callback is called before each element html opening tag
onElementStopThis callback is called after each element html closing tag
onElementThis callback is called to render each element html opening tag attributes
onElementPrependThis callback is called after each element html opening tag
onElementAppendThis callback is called before each element html closing tag

To register a stepper into the datagrid, you can use the setStepper method:

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());

An unidirectionnal connection is done between the two class, so, a stepper can only have one DataGrid as parent, and in return, a DataGrid can only have one stepper.

To register a callback, you'll must use the stepper addCallback method. This one take as argument the callback name, the function to use as a closure, the html safe state as optional, and an array of additionnal data.

The name of the callback can be one of the previous callback or any of template callback if you use a personal template. An inexisting callback name does not create error but it will never call.

In this example, we can see that the result of callbacks are naturally escaped, but the third argument allow to display html tags by passing true.

// in php file$dataGrid = newDataGridContainer();
$dataGrid->setStepper(newDataGridStepper());
// This one display the header before each values$dataGrid->getStepper()->addCallback("onElementPrepend", function($type, $process, $row, $data){
return$data['header']." : ";
});
// This one display a title before the datagrid$dataGrid->getStepper()->addCallback("onGridStart", function($type, $process, $row, $data){
return"<h3>See our awesome datagrid : </h3>";
}, true);
// This one set the style of the header at 'color: red'$dataGrid->getStepper()->addCallback("onHead", function($type, $process, $row, $data){
return"style='color: ".$data["color"].";'";
}, false, array("color"=>"red"));

The function registered can take four arguments, given by the stepper. This arguments may be null in function of the place in the template. The first argument is the type of the elements. The second is the total processed data as array, the third will be the current row and the fourth is the array of additional data.

  • The type of element is an integer. 0 is an object type and 1 is array.
  • The processed data is an array that contain the type as 'type' named index and each rows into integer index.
  • The current row is an array that contain the current element as 'primary' named index and each data into integer index.
  • The additional data is an array defined on callback registering and where we find in addition the current row index, the current element index, the current header name and the current DataGridStepper, respectively into 'index', 'element', 'header' and 'stepper' named index. Note that if you use this index into the callback definition, they will be override before the callback calling.

Note that the callback must return a string and callbacks have different access to the the variables. They exists but would be null. Refer to the following table to see the access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onGridStart
onGridStop
onGrid
onGridPrepend
onGridAppend
onHeadStart
onHeadStop
onHead
onHeadPrepend
onHeadAppend
onHeadElementStart
onHeadElementStop
onHeadElement
onHeadElementPrepend
onHeadElementAppend
onBodyStart
onBodyStop
onBody
onBodyPrepend
onBodyAppend
onRowStart
onRowStop
onRow
onRowPrepend
onRowAppend
onElementStart
onElementStop
onElement
onElementPrepend
onElementAppend

Consider to use a service to define the callbacks.

Create your own template

You can define your own template to display you'r datagrid by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderDatagrid twig function :

{# in your template file #}
{{ renderDatagrid(data, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:datagrid.html.twig' %}
{% blockdatagrid %}
{% blockheader %}
{{ parent() }}
{% endblock %}
{% blockbody %}
{% blockrow %}
{{ parent() }}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
datagridthe main datagrid block.
headerthe head block.
bodythe datagrid block that contain each rows.
rowThe row block that contain the row loop.

The variables are defined into the followed blocks :

Variable nameBlock name
onGridStartdatagrid
onGridStopdatagrid
onGriddatagrid
onGridPrependdatagrid
onGridAppenddatagrid
onHeadStartheader
onHeadStopheader
onHeadheader
onHeadPrependheader
onHeadAppendheader
onHeadElementStartheader
onHeadElementStopheader
onHeadElementheader
onHeadElementPrependheader
onHeadElementAppendheader
onBodyStartbody
onBodyStopbody
onBodybody
onBodyPrependbody
onBodyAppendbody
onRowStartrow
onRowStoprow
onRowrow
onRowPrependrow
onRowAppendrow
onElementStartrow
onElementStoprow
onElementrow
onElementPrependrow
onElementAppendrow
by yourself

Note, the DataGridContainer is passed to the template into the variable 'data'.

To get data from the DataGridContainer, you'll must use the getData method.

{# in your template file #}
{% setdatas= data.getData() %}

To get the stepper from the DataGridContainer, you'll must use the getStepper method.

{# in your template file #}
{% setstepper= data.getStepper() %}

To render a callback, you must use the datagc function (datagridRenderCallback). This function take three arguments :

  • The callback name that will be call from the stepper
  • The current row index and element index as formated string
  • The stepper instance

The formated string of the index is "i:e" where 'i' is the row index and 'e' the element index. If no one is define at the current template place, the function accept null. If only the row index is define, it can be passed alone.

The headers are accessibles from the getHeader method of the DataGridContainer (passed as 'data' variable).

{# in your template file #}
{{ datagc("onAcmeCallback", null, data.getStepper()) }}
<table>
{% if data.getHeader() is notempty %}
<tr>
{% forheadin data.getHeader() %}
<th>{{ head }}</th>
{% endfor %}
</tr>
{% forrowin data.getData() %}
<tr>
{{ datagc("onAcmeRow", loop.index0, data.getStepper()) }}
{% setrowIndex=loop.index0 %}
{% forelementinrow %}
<td>
{{ datagc("onAcmeElement", rowIndex~':'~loop.index0, data.getStepper()) }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Use pagination

The 1.1.0 version introduce pagination usage.

The main pagination class must be instanciate into a php context by using DataGridPaginator class.

This class can be instanciate withe three arguments :

  • The data to display in an array as first argument
  • The integer page to render as second argument
  • The integer limit of objects to display as third argument

All of these arguments are optional, the DataGridPaginator class can be instanciate without arguments.

// In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
/*  * Instanciate with arguments *  * In this example, we instanciate the paginator * with a 10 index array, on page 2, with 4 data * per page.  */$paginator = newDataGridPaginator($datas, 2, 4);

The paginator allow to be instanciate without arguments, so it purpose some setters to perform it's task.

//In a php context/* * Note that this example render the * same result as the previous example. */$paginator = newDataGridPaginator();
$paginator->setPage(2)
->setLimit(4)
->setData(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

To use pagination, the paginator class purpose access to several getter methods, as followed :

Method nameResult
pageIsset()Return true if the current requested page exist
getMaxPage()Return the maximum ammount of page that the current data count and limit allow
getPageData()Return the current page data

Note that the DataGridPaginator class auto process the data selection when the limit or the data is defined.

The usage of unexisting page, sub zero limit or empty data does not create error.

To use it with the DataGridContainer instance, simply use :

//In a php context$datas = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$paginator = newDataGridPaginator($datas, 2, 4);
$data = newDataGridContainer($paginator->getPageData());

Use pagination in twig

The 1.1.0 version introduce pagination usage in a twig context.

To display the paginator page selector, the DataGridBundle purpose the renderPaginator() function. It take the paginator class as first argument.

{# in twig template #}
{{ renderPaginator(pager) }}

The paginator, same as DataGridContainer allow to use a DataGridStepper to customize the rendering template. The allowed callbacks are :

Callback namedescription
onPagerStartThis callback is called before the paginator container opening tag
onPagerStopThis callback is called after the paginator container closing tag
onPagerThis callback is called to render the paginator container html opening tag attributes, after the tag name and before the tag end
onPagerPreppendThis callback is called after the paginator container html opening tag
onPagerAppendThis callback is called before the paginator container html closing tag
onPagerListStartThis callback is called before the paginator list opening tag
onPagerListStopThis callback is called after the paginator list closing tag
onPagerListThis callback is called to render the paginator list html opening tag attributes, after the tag name and before the tag end
onPagerListPreppendThis callback is called after the paginator list html opening tag
onPagerListAppendThis callback is called before the paginator list html closing tag
onSelectorContainerStartThis callback is called before each paginator element container opening tag
onSelectorContainerStopThis callback is called after each paginator element container closing tag
onSelectorContainerThis callback is called to render each paginator element container html opening tag attributes, after the tag name and before the tag end
onSelectorContainerPreppendThis callback is called after each paginator element container html opening tag
onSelectorContainerAppendThis callback is called before each paginator element container html closing tag
onSelectorStartThis callback is called before each paginator element opening tag
onSelectorStopThis callback is called after each paginator element closing tag
onSelectorThis callback is called to render each paginator element html opening tag attributes, after the tag name and before the tag end
onSelectorPreppendThis callback is called after each paginator element html opening tag
onSelectorAppendThis callback is called before each paginator element html closing tag
onHrefThis callback is called into the link tag's href attribute ‼️ must passing 'true' on html safe state argument of addCallback function.

Referer to the following table to see callbacks variable access :

Callback nametypeprocesseddata[row]data[index]data[element]data[header]data[stepper]
onPagerStart
onPagerStop
onPager
onPagerPreppend
onPagerAppend
onPagerListStart
onPagerListStop
onPagerList
onPagerListPreppend
onPagerListAppend
onSelectorContainerStart
onSelectorContainerStop
onSelectorContainer
onSelectorContainerPreppend
onSelectorContainerAppend
onSelectorStart
onSelectorStop
onSelector
onSelectorPreppend
onSelectorAppend
onHref

The onHref callback have access to a data['page'] and data['limit'] variables.

Create your own template

You can define your own template to display you'r paginator by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginator twig function :

{# in your template file #}
{{ renderPaginator(pager, "AcmeBundle:Default:YourTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blockpager %}
{% blockpagedList %}
{% blockselector %}
{% endblock %}
{% endblock %}
{% endblock %}
Block namedescription
pagerthe main paginator block.
pagedListthe page list.
selectorthe paginator block that contain each elements.

The variables are defined into the followed blocks :

Variable nameBlock name
onPagerStartpager
onPagerStoppager
onPagerpager
onPagerPreppendpager
onPagerAppendpager
onPagerListStartpagedList
onPagerListStoppagedList
onPagerListpagedList
onPagerListPreppendpagedList
onPagerListAppendpagedList
onSelectorContainerStartselector
onSelectorContainerStopselector
onSelectorContainerselector
onSelectorContainerPreppendselector
onSelectorContainerAppendselector
onSelectorStartselector
onSelectorStopselector
onSelectorselector
onSelectorPreppendselector
onSelectorAppendselector
onHrefselector
by yourself

Note that the paginator instance is passed as 'pager' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use a loop :

{# in your twig template #}
{% forpageinstart..end %}
{# the element display here #}
{% endfor %}

The 'start' and 'end' variables are defined by the twig extension class to allow the page selection list amount limit.

Limit the page selection list amount

The renderPaginator() twig function purpose to limit the page amount to display by passing an integer as third arguments. This integer represent an interval, if you define it at 3, a page will be before the current page, and a page will be displayed after the current page.

The default comportment of the function will display an odd number of page and does not display unexisting pages.

{# in your twig template #}
{{ renderPaginator(pager, null, 5) }}

Limit pagination

The pagination limit is setted by the paginator class in a php context, but it possible to purpose a limit selector to the client.

This action is performed by passing an array of allowed limits behind the paginator 'setAllowedLimits(array())' method. This information is used into the template for hydrate the select options tags.

The limit pagination twig extension will display a form to manage the limit choice. This form is created from a Cscfa\Bundle\DataGridBundle\Form\Type\PaginatorLimit type, that contain the current page and limit information, and a limit.

The rendering of the form is perform by the {{ renderPaginatorLimit(pager) }} twig function. This function accept as second argument a template name to override the configuration's defined template.

{# in your twig template #}
{{ renderPaginatorLimit(pager) }}
{# or #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}

As the other template, this one use the pager stepper to customize some informations, but many of callbacks must return an array instead of string. To do it, it is necessary to pass 'true' as third argument.

Refer to the list of callbacks :

Callback namereturn typedescription
onLimitStartstringThis callback is called before the form opening html tag
onLimitStopstringThis callback is called after the form closing html tag
onLimitFirstarrayThis callback is called as form_start() options attributes
onLimitEndarrayThis callback is called as form_end() options attributes
onLimitPrependstringThis callback is called after the form opening html tag
onLimitAppendstringThis callback is called before the form closing html tag
onSelectLabelStartstringThis callback is called before the select label html tag
onSelectLabelStopstringThis callback is called after the select label html tag
onSelectLabelarrayThis callback is called as select form_label() options attributes
onSelectStartstringThis callback is called before the select html tag
onSelectStopstringThis callback is called after the select html tag
onSelectarrayThis callback is called as select form_widget() options attributes
onSubmitStartstringThis callback is called before the submit button html tag
onSubmitStopstringThis callback is called after the submit button html tag
onSubmitarrayThis callback is called as submit button form_widget() options attributes

To access to the new limit, a controller action must receive the form informations. The route can be defined by the 'inLimitFirst' callback.

//in your controlleruseSymfony\Bundle\FrameworkBundle\Controller\Controller;
useCscfa\Bundle\DataGridBundle\Objects\PaginatorLimitForm;
class AcmeController extends Controller
{
publicfunctionlimitAction(Request$request)
{
$paginatorLimitForm = newPaginatorLimitForm();
$paginatorLimitForm->setAllowedLimits(array(5, 10, 25, 50, 100));
$limitForm = $this->createForm("paginatorLimit", $paginatorLimitForm);
if ($request->getMethod() === "POST") {
$limitForm->handleRequest($request);
$choice = $paginatorLimitForm->getLimit();
$value = $paginatorLimitForm->getAllowedLimits()[$choice];
$lastLimit = $paginatorLimitForm->getLastLimit();
$page = $paginatorLimitForm->getPage();
// render the template
} else {
// render the template
}
}
}

Create your own template

You can define your own template to display you'r paginator limit form by configure it into the config.yml symfony file.

# in app/config/config.ymlcscfa_data_grid:
paginator_limit_template: AcmeBundle:Default:YourTemplate.html.twig

A second choice would be by passing the template by the renderPaginatorLimit twig function :

{# in your template file #}
{{ renderPaginatorLimit(pager, "AcmeBundle:Default:AcmeTemplate.html.twig") }}
by extend

You can also extend of the DataGridBundle template. This one is composed with blocks. You will find the following blocks :

{# in your template file #}
{% extends'CscfaDataGridBundle:Default:paginatorPageSelector.html.twig' %}
{% blocklimit %}
{% blockselect %}
{{ parent() }}
{% endblock %}
{% blocksubmit %}
{{ parent() }}
{% endblock %}
{% endblock %}
Block namedescription
limitthe main paginator limit block.
selectthe select block.
submitthe submit block.

The variables are defined into the followed blocks :

Variable nameBlock name
onLimitStartlimit
onLimitStoplimit
onLimitFirstlimit
onLimitEndlimit
onLimitPrependlimit
onLimitAppendlimit
onSelectLabelStartselect
onSelectLabelStopselect
onSelectLabelselect
onSelectStartselect
onSelectStopselect
onSelectselect
onSubmitStartsubmit
onSubmitStopsubmit
onSubmitsubmit
by yourself

Note that the paginator instance is passed as 'pager' variable and the form view as 'form' variable.

The callback definition of the paginator template is the same as the DataGrid template with the 'datagc' function usage.

To display the elements, the simple way is to use the twig form functions :

{# in your twig template #}
{{ form_start(form) }}
{{ form_row(form.limit) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}

About

The DataGridBundle is a symfony2 datagrid rendering library

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages