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

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

Documentation

SearchBuilder Extension

Let users compose grouped search conditions

When To Use

Use SearchBuilder when users need to combine several conditions, such as “age over 50 and city is Paris, or name starts with Al”, without a dedicated filter form.

Minimal Example

namespace App\DataTable;

use App\Entity\Employee;
use Pentiminax\UX\DataTables\Attribute\AsDataTable;
use Pentiminax\UX\DataTables\Model\AbstractDataTable;
use Pentiminax\UX\DataTables\Model\DataTable;

#[AsDataTable(Employee::class)]
final class EmployeeDataTable extends AbstractDataTable
{
    public function configureDataTable(DataTable $table): DataTable
    {
        return $table->searchBuilder();
    }
}

searchBuilder() registers the extension and adds the searchBuilder feature to the top1 layout row. Pass position: 'topStart' to place it elsewhere, or declare Feature::SEARCH_BUILDER in layout() yourself and register the extension with addExtension(new SearchBuilderExtension()). A layout that places the feature without the extension is deprecated since 1.3 and throws in 2.0.

Advanced Example

use Pentiminax\UX\DataTables\Enum\SearchBuilderLogic;

$dataTable->searchBuilder(
    columns: [1, 2, 3],
    depthLimit: 2,
    logic: SearchBuilderLogic::Or,
    preDefined: [
        'criteria' => [['data' => 'Age', 'condition' => '>', 'value' => [50]]],
        'logic' => 'AND',
    ],
);

Only options that differ from the DataTables defaults reach the browser (an empty payload for searchBuilder() without arguments). filterChanged is a JavaScript callback and cannot be configured from PHP.

Date Columns

SearchBuilder needs the DataTables DateTime extension as soon as the table has a date column. The bundle loads datatables.net-datetime with SearchBuilder, but not its stylesheet, so import it once to style the date picker:

// assets/app.js
import 'datatables.net-datetime/dist/dataTables.dateTime.min.css'

With AssetMapper, run php bin/console importmap:require datatables.net-datetime datatables.net-datetime/dist/dataTables.dateTime.min.css first. With Webpack Encore, import datatables.net-datetime/css instead.

Server-Side Processing

On server-side tables the bundle reads the searchBuilder request parameter and ANDs the result with the other filters. Conditions supported: =, !=, <, <=, >=, >, between, !between, null, !null, starts, !starts, contains, !contains, ends and !ends.

The parameter is validated strictly. An unknown logic or condition, a malformed node, more than 5 nesting levels or 50 nodes, or more than 2 values per criterion answers HTTP 400 rather than an unfiltered table. Incomplete criteria (a blank field or value) are skipped, as in the browser.

  • columns only limits what the browser offers. The server accepts any searchable column, so call setSearchable(false) on a column to block it: the builder leaves it out, and a request naming it or an unknown column answers HTTP 400.
  • The without condition is hidden, because the server cannot apply it.
  • A criterion whose value cannot be bound to the field type (for example text for an integer column, or 2.5 for an integer) matches nothing instead of raising a database error.
  • Dates compare by whole day, and negated conditions keep rows where the field is NULL.
  • API Platform tables cannot apply SearchBuilder criteria: rendering throws a LogicException. ArrayDataProvider rejects them with HTTP 400.
  • LIKE conditions are case-insensitive and escape % and _.
  • Select-based conditions fall back to text inputs, and custom conditions are not supported.

Frequent Pitfalls

  • Expecting array conditions (without) to work server-side: the builder hides them.
  • Hiding a column from the table but leaving it searchable: it still appears in the builder unless you restrict columns or call setSearchable(false).