Personalization
The data tables can be personalized, which can be helpful when working with many columns, by giving the user ability to:
- set the priority (order) of the columns;
- show or hide specific columns;
Screenshots
Prerequisites
To begin with, make sure the Symfony UX integration is enabled. Then, enable the personalization controller in your assets/controllers.json
file:
{
"controllers": {
"@kreyu/data-table-bundle": {
"personalization": {
"enabled": true
}
}
}
}
Toggling the feature
By default, the personalization feature is disabled for every data table.
You can change this setting globally using the package configuration file, or use personalization_enabled
option:
kreyu_data_table:
defaults:
personalization:
enabled: true
use Symfony\Config\KreyuDataTableConfig;
return static function (KreyuDataTableConfig $config) {
$defaults = $config->defaults();
$defaults->personalization()->enabled(true);
};
use Kreyu\Bundle\DataTableBundle\Type\AbstractDataTableType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ProductDataTableType extends AbstractDataTableType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'personalization_enabled' => true,
]);
}
}
use App\DataTable\Type\ProductDataTableType;
use Kreyu\Bundle\DataTableBundle\DataTableFactoryAwareTrait;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ProductController extends AbstractController
{
use DataTableFactoryAwareTrait;
public function index()
{
$dataTable = $this->createDataTable(
type: ProductDataTableType::class,
query: $query,
options: [
'personalization_enabled' => true,
],
);
}
}
Personalization is enabled, but submitting the personalization form does nothing?
Ensure that the handleRequest()
method of the data table is called:
class ProductController
{
public function index(Request $request)
{
$dataTable = $this->createDataTable(...);
$dataTable->handleRequest($request);
}
}
Saving applied personalization
By default, the personalization feature persistence is disabled for every data table.
You can configure the persistence globally using the package configuration file, or its related options:
kreyu_data_table:
defaults:
personalization:
persistence_enabled: true
# if persistence is enabled and symfony/cache is installed, null otherwise
persistence_adapter: kreyu_data_table.sorting.persistence.adapter.cache
# if persistence is enabled and symfony/security-bundle is installed, null otherwise
persistence_subject_provider: kreyu_data_table.persistence.subject_provider.token_storage
use Symfony\Config\KreyuDataTableConfig;
return static function (KreyuDataTableConfig $config) {
$defaults = $config->defaults();
$defaults->personalization()
->persistenceEnabled(true)
// if persistence is enabled and symfony/cache is installed, null otherwise
->persistenceAdapter('kreyu_data_table.sorting.persistence.adapter.cache')
// if persistence is enabled and symfony/security-bundle is installed, null otherwise
->persistenceSubjectProvider('kreyu_data_table.persistence.subject_provider.token_storage')
;
};
use Kreyu\Bundle\DataTableBundle\Persistence\PersistenceAdapterInterface;
use Kreyu\Bundle\DataTableBundle\Persistence\PersistenceSubjectProviderInterface;
use Kreyu\Bundle\DataTableBundle\Type\AbstractDataTableType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ProductDataTableType extends AbstractDataTableType
{
public function __construct(
private PersistenceAdapterInterface $persistenceAdapter,
private PersistenceSubjectProviderInterface $persistenceSubjectProvider,
) {
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'personalization_persistence_enabled' => true,
'personalization_persistence_adapter' => $this->persistenceAdapter,
'personalization_persistence_subject_provider' => $this->persistenceSubjectProvider,
]);
}
}
use App\DataTable\Type\ProductDataTableType;
use Kreyu\Bundle\DataTableBundle\DataTableFactoryAwareTrait;
use Kreyu\Bundle\DataTableBundle\Persistence\PersistenceAdapterInterface;
use Kreyu\Bundle\DataTableBundle\Persistence\PersistenceSubjectProviderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ProductController extends AbstractController
{
use DataTableFactoryAwareTrait;
public function __construct(
private PersistenceAdapterInterface $persistenceAdapter,
private PersistenceSubjectProviderInterface $persistenceSubjectProvider,
) {
}
public function index()
{
$dataTable = $this->createDataTable(
type: ProductDataTableType::class,
query: $query,
options: [
'personalization_persistence_enabled' => true,
'personalization_persistence_adapter' => $this->persistenceAdapter,
'personalization_persistence_subject_provider' => $this->persistenceSubjectProvider,
],
);
}
}
Default personalization
There are two ways to configure the default personalization data for the data table:
- using the columns
priority
,visible
andpersonalizable
options (recommended); - using the data table builder's
setDefaultPersonalizationData()
method;
use Kreyu\Bundle\DataTableBundle\DataTableBuilderInterface;
use Kreyu\Bundle\DataTableBundle\Type\AbstractDataTableType;
use Kreyu\Bundle\DataTableBundle\Personalization\PersonalizationData;
use Kreyu\Bundle\DataTableBundle\Personalization\PersonalizationColumnData;
class ProductDataTableType extends AbstractDataTableType
{
public function buildDataTable(DataTableBuilderInterface $builder, array $options): void
{
// using the columns options:
$builder
->addColumn('id', NumberColumnType::class, [
'priority' => -1,
])
->addColumn('name', TextColumnType::class, [
'visible' => false,
])
->addColumn('createdAt', DateTimeColumnType::class, [
'personalizable' => false,
])
;
// or using the data table builder's method:
$builder->setDefaultPersonalizationData(new PersonalizationData([
new PersonalizationColumnData(name: 'id', priority: -1),
new PersonalizationColumnData(name: 'name', visible: false),
]));
// or by creating the personalization data from an array:
$builder->setDefaultPersonalizationData(PersonalizationData::fromArray([
// each entry default values: name = from key, priority = 0, visible = false
'id' => ['priority' => -1],
'name' => ['visible' => false],
]));
}
}
Events
The following events are dispatched when personalize()
method of the DataTableInterface
is called:
PRE_PERSONALIZE
Dispatched before the personalization data is applied to the data table. Can be used to modify the personalization data, e.g. to dynamically specify priority or visibility of the columns.
POST_PERSONALIZE
Dispatched after the personalization data is applied to the data table and saved if the personalization persistence is enabled. Can be used to execute additional logic after the personalization is applied.
The dispatched events are instance of the DataTablePersonalizationEvent
:
use Kreyu\Bundle\DataTableBundle\Event\DataTablePersonalizationEvent;
class DataTablePersonalizationListener
{
public function __invoke(DataTablePersonalizationEvent $event): void
{
$dataTable = $event->getDataTable();
$personalizationData = $event->getPersonalizationData();
// for example, modify the personalization data, then save it in the event
$event->setPersonalizationData($personalizationData);
}
}