Documentation & Demo Homepage : http://www.table-bundle.com/
This bundle gives a simple way to generate and manage tables based on Symfony. It's allow also :
- Flexibility
- Pagination (automated)
- Searching (automated)
- Sorting (automated)
- Theming
- Extensions
- Sub-tables (automated)
- Rows selection (automated)
- Export (PDF, XSL, CSV) (automated)
- Download TableBundle
- Enable the Bundle
- Create/Custom new column type extension
- Sub-tables
- Examples
- Result & Screenshots
This can be done in several ways, depending on your preference. The first method is the standard Symfony2 method.
Using Composer
Add TableBundle in your composer.json:
{
"require": {
"emc/table-bundle": "*"
}
}
Now tell composer to download the bundle by running the command:
$ php composer.phar update emc/table-bundle
Using submodules
If you prefer instead to use git submodules, then run the following:
$ git submodule add https://github.com/chafiq/TableBundle.git vendor/emc/table-bundle/EMC/TableBundle/
$ git submodule update --init
Note that using submodules requires manually registering the EMC
namespace to your autoloader:
<?php
// app/autoload.php
$loader->registerNamespaces(array(
// ...
'EMC' => __DIR__.'/../vendor/bundles',
));
Finally,
Enable the bundle in the kernel:
<?php
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new EMC\TableBundle\EMCTableBundle(),
);
}
Enable the routing config :
# app/config/routing.yml
emc_table:
resource: "@EMCTableBundle/Resources/config/routing.yml"
prefix: /
- jQuery >= v1.4.2 : http://jquery.com/download/
- emc/xmlhttprequest-bundle : 3.0
PHP : Column type class
<?php
namespace Acme\MyBundle\Table\Column;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class CustomType extends ColumnType {
public function buildView(array &$view, ColumnInterface $column, array $data, array $options) {
parent::buildView($view, $column, $data, $options);
/* Add you column data view here. You can access to them in the twig extension widget */
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
parent::setDefaultOptions($resolver);
/* define you parameters here */
}
public function getName() {
return 'custom';
}
}
Twig : Column type template
{# Acme/MyBundle/Resources/views/Table/Column/custom.html.twig #}
{% block custom_widget %}
{# here you can edit the content of TD element (Cell). #}
{% endblock %}
Config : Column type service
# Acme/MyBundle/Resources/config/services.yml
services:
...
my_custom_column_type:
class: Acme\MyBundle\Table\Column\CustomType
tags:
- { name: column.type, alias: custom }
Controller Code
/* Controller */
...
$table = $factory->create(new MyTableType(), null, array(
...
'caption' => 'My sub table example',
'subtable' => new MySubTableType(),
'subtable_params' => array('cityId' => 'c.id'),
'subtable_options' => array( /* can take the same options as the root table */ )
...
);
Table Type Code
<?php
namespace Acme\MyBundle\Table\Type;
use EMC\TableBundle\Table\Type\TableType;
use EMC\TableBundle\Table\TableBuilderInterface;
use Doctrine\Common\Persistence\ObjectManager;
class MySubTableType extends TableType {
public function buildTable(TableBuilderInterface $builder, array $options) {
$builder->add('store', 'text', array(
'params' => array('ci.name'),
'title' => 'Center of interest',
'allow_filter' => true,
'allow_sort' => true
));
$builder->add('address', 'text', array(
'params' => array('ci.address', 'ci.zipcode', 'c.name'),
'format' => '%s %s %s',
'title' => 'Address',
'allow_filter' => true,
'allow_sort' => true
));
$builder->add('delete', 'button', array(
'icon' => 'remove',
'attrs' => class('attrs' => 'btn-xs')
));
$builder->add('add', 'button', array(
'icon' => 'plus',
'attrs' => class('attrs' => 'btn-xs')
));
}
public function getName() {
return 'my-sub-table';
}
public function getQueryBuilder(ObjectManager $entityManager, array $params) {
return $entityManager
->getRepository('AcmeMyBundle:CenterInterest')
->createQueryBuilder('ci')
->innerJoin('ci.city', 'c')
->where('c.id = :cityId')
->setParameter('cityId', $params['cityId']); /* this parameter was defined in the subtable_options. $params is poputated in the TableType::buildSubtableParams and are passed to this method */
}
}
Consider that we have two data base tables :
- city : #id, name, createdAt, stateid
- state : #id, name
use Symfony\Component\HttpFoundation\Request;
use Acme\MyBundle\Table\Type\MyTableType
public function indexAction(Request $request) {
/* @var $factory \EMC\TableBundle\Table\TableFactory */
$factory = $this->get('table.factory');
$table = $factory ->create(
new MyTableType(),
null,
array('caption' => 'My table example')
)
->getTable();
return $this->render('AcmeMyBundle:Table:index.html.twig', array('table' => $table));
}
...
{% stylesheets 'bundles/emctable/css/style.css' filter='cssrewrite' %}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% javascripts 'bundles/emctable/js/EMCTable.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
<div class="container">{{ table(table) }}</div>
...
<?php
namespace Acme\MyBundle\Table\Type;
use EMC\TableBundle\Table\Type\TableType;
use EMC\TableBundle\Table\TableBuilderInterface;
use Doctrine\Common\Persistence\ObjectManager;
class MyTableType extends TableType {
public function buildTable(TableBuilderInterface $builder, array $options) {
$builder->add('id', 'anchor', array(
'route' => 'edit_route',
'params' => array('id' => 'c.id'),
'format' => '#%s',
'title' => '#',
'allow_sort' => true
));
$builder->add('state', 'text', array(
'params' => array('s.name'),
'format' => '%s',
'title' => 'State',
'allow_filter' => true,
'allow_sort' => true
));
$builder->add('city', 'text', array(
'params' => array('c.name', 'c.id'),
'format' => '%s (#%d)',
'title' => 'City',
'allow_filter' => true,
'allow_sort' => true
));
$builder->add('createdAt', 'datetime', array(
'params' => array('t.createdAt'),
'title' => 'Date',
'allow_sort' => true
));
$builder->add('delete', 'button', array(
'icon' => 'remove',
'text' => 'Delete',
'attrs' => class('attrs' => 'btn-xs')
));
$builder->add('add', 'button', array(
'icon' => 'plus',
'attrs' => class('attrs' => 'btn-xs')
));
$builder->add('status', 'icon', array(
'params' => array('c.id'),
'format' => function($id) { return $id % 2 ? 'star' : 'star-o'; }
));
$builder->add('pdf', 'image', array(
'asset_url' => 'bundles/acmesandbox/images/pdf.jpg'
));
}
public function getName() {
return 'my-table';
}
public function getQueryBuilder(ObjectManager $entityManager, array $options) {
return $entityManager
->getRepository('AcmeMyBundle:City')
->createQueryBuilder('c')
->innerJoin('t.state', 's');
}
}