Type to search columns, filters, options, and extensions.

↑↓ to navigate · Enter to open · Esc to close

Documentation

Configuration

Configure DataTables defaults and bundle options

Configure bundle-wide defaults in config/packages/data_tables.yaml.

Full Configuration Reference

data_tables:
  max_page_length: 1000
  options:
    language: en-GB
    layout:
      topStart: pageLength
      topEnd: search
      bottomStart: info
      bottomEnd: paging
    lengthMenu: [10, 25, 50]
    pageLength: 10
    paging:
      boundaryNumbers: true
      buttons: 7
      firstLast: true
      numbers: true
      previousNext: true
    stateSave: false
    showHeaderResetButton: false
  table_attributes:
    class: 'table'
  extensions:
    buttons: [csv, excel, pdf, print]
    select:
      style: single

max_page_length

Upper bound applied to the length parameter of every server-side Ajax request, so a crafted length=999999 cannot make a table hydrate its whole dataset.

data_tables:
  max_page_length: 1000

DataTables sends length=-1 for its “show all” entry. That is honored only when the table offers it, that is when lengthMenu() declares -1; otherwise the request is served with max_page_length rows. A negative start is clamped to 0.

// Show all is honored: this table offers it.
$table->lengthMenu([10, 25, -1]);

// Show all is capped to max_page_length: this table never offers it.
$table->lengthMenu([10, 25]);

A page size the table declares itself escapes the bound instead of being capped by it, because the client paginates with that size: pageLength() and the entries of lengthMenu() are honored even above max_page_length. Only those exact sizes escape it. Any other length a request carries is still capped, so a table declaring 2000 still serves a crafted length=1500 with max_page_length rows, and a refused “show all” still falls back to max_page_length.

// Served in full: the table asked for these page sizes.
$table->pageLength(2000)->lengthMenu([500, 2000]);

Exports are not affected: they read every filtered row by design.

Options

language

Sets the default language locale for DataTables UI elements. The bundle translates locale codes into the correct CDN URL for DataTables language files.

When no language is configured, each table follows the locale of the current request: fr, fr_FR, and fr-CA load the bundled French catalog, and en loads the English one. A locale without a bundled catalog keeps the DataTables built-in English strings. Set language here, or call language() on a table, to pin it instead.

data_tables:
  options:
    language: fr-FR # French
    # language: de-DE  # German
    # language: es-ES  # Spanish

Supported locales: Any locale supported by DataTables i18n.

layout

Controls the positioning of DataTables UI features. Each position accepts a feature name, an array of features, null to hide, or a DataTables feature object.

data_tables:
  options:
    layout:
      topStart: pageLength
      topEnd: search
      bottomStart: info
      bottomEnd: paging

Multi-features per position:

data_tables:
  options:
    layout:
      topEnd: [search, buttons]
      bottomStart: null

Available positions:

PositionDescription
topStartTop-left area
topEndTop-right area
bottomStartBottom-left area
bottomEndBottom-right area
topFull top row
bottomFull bottom row
top2Start, top2End, ...Additional numbered rows

Available features:

FeatureDescription
pageLengthPage length selector
searchGlobal search input
infoTable info summary
pagingPagination controls
buttonsButtons extension slot
searchBuilderSearch builder UI
searchPanesSearch panes UI

lengthMenu

Defines the available page length options shown in the dropdown:

data_tables:
  options:
    lengthMenu: [10, 25, 50, 100]

You can also provide custom labels:

// In PHP
$table->lengthMenu([
    [10, 25, 50, -1],
    [10, 25, 50, 'All']
]);

Declaring -1 also tells the bundle that an unbounded Ajax page is intentional for this table. See max_page_length.

pageLength

Sets the initial number of rows displayed:

data_tables:
  options:
    pageLength: 25

paging

Sets the default paging layout feature for every table (button count, first/last, …), not the top-level DataTables boolean. At render time the bundle injects these keys into unmarked layout paging slots (bottomEnd: paging by default). An explicit { paging: { … } } object in layout wins and is not overwritten.

Only the keys you declare need to be listed; the others keep their defaults.

data_tables:
  options:
    paging:
      buttons: 5
      firstLast: false
KeyDefaultDescription
boundaryNumberstrueAlways show the first and last page numbers
buttons7Number of page number buttons
firstLasttrueShow the first and last buttons
numberstrueShow the page number buttons
previousNexttrueShow the previous and next buttons

Override it per table with $table->paging(...), or disable pagination entirely with $table->withoutPaging().

stateSave

Persist each table’s state (page, ordering, search, page length, and the applied filters) in the browser. Both keys are optional and absent by default.

data_tables:
  options:
    stateSave: true

Override it per table with $table->stateSave(false).

showHeaderResetButton

Show a Reset button next to the filter toggle on every table that declares filters. It only appears while at least one filter is applied.

data_tables:
  options:
    showHeaderResetButton: true

A table overrides it with $table->showHeaderResetButton() or $filters->showHeaderResetButton(); see Reset button in the header.

Table Attributes

Default HTML attributes for the generated <table> element:

data_tables:
  table_attributes:
    class: 'table table-striped table-hover'
    id: 'my-default-table'

These can be overridden per-table in Twig:

{{ render_datatable(table, {'class': 'custom-class'}) }}

Extensions

Configure default extensions enabled for all tables:

data_tables:
  extensions:
    buttons: [csv, excel, pdf, print, copy, colvis]
    select:
      style: single # or 'multi'

Buttons Extension

extensions:
  buttons:
    - csv
    - excel
    - pdf
    - print
    - copy
    - colvis # Column visibility toggle

Select Extension

extensions:
  select:
    style: single # Single row selection
    # style: multi  # Multiple row selection

A table that declares bulk actions does not use this default: it gets a multi-row selection with checkboxes instead. Only a Select extension the table configures itself replaces that one.

Per-Table Override

Bundle defaults apply to every table declared as an AbstractDataTable class, and can be overridden for individual tables:

use Pentiminax\UX\DataTables\Enum\Language;
use Pentiminax\UX\DataTables\Model\DataTable;

public function configureDataTable(DataTable $table): DataTable
{
    return $table
        ->pageLength(50)          // Override default 10
        ->language(Language::DE); // Override default en-GB
}

Global Defaults in PHP

Implement DataTableDefaultsConfiguratorInterface to configure every table in one place. The service is autoconfigured; use the datatables.defaults_configurator tag priority to order several of them. Defaults apply in this order, and each layer overrides the previous one: the data_tables YAML, then the configurators, then the table’s own configureDataTable().

namespace App\DataTable;

use Pentiminax\UX\DataTables\Contracts\DataTableDefaultsConfiguratorInterface;
use Pentiminax\UX\DataTables\Model\DataTable;

final class AppDataTableDefaults implements DataTableDefaultsConfiguratorInterface
{
    public function configure(DataTable $table): void
    {
        $table->stateSave(true)->pageLength(25);
    }
}

Configurators only receive the DataTable. They cannot change Ajax routes, tokens, or the table purpose validation, and no configuration key can disable those checks.

Validation

  • extensions.select.style and extensions.buttons must use the values of the SelectStyle and ButtonType enums. Other values compile with a deprecation since 1.3, still fail with a ValueError when a table is built (as in 1.2.1), and are rejected at compile time in 2.0.
  • When both are set, options.pageLength should be one of the options.lengthMenu entries. A mismatch keeps working but is deprecated since 1.3 and throws in 2.0.
  • edit_modal.default_title defaults to the bundle’s own edit_modal.default_title key, translated from the DataTables domain. Any other value is passed to your modal template, which translates it in the messages domain.

Environment Variables

data_tables:
  max_page_length: '%env(int:DATATABLES_MAX_PAGE_LENGTH)%'
  options:
    stateSave: '%env(bool:DATATABLES_STATE_SAVE)%'

parameters:
  env(DATATABLES_MAX_PAGE_LENGTH): '1000'
  env(DATATABLES_STATE_SAVE): 'false'

Environment-Specific Configuration

Use Symfony’s configuration system for different environments:

# config/packages/data_tables.yaml (default)
data_tables:
  options:
    pageLength: 10

# config/packages/dev/datatables.yaml
data_tables:
  options:
    pageLength: 5 # Smaller for development