DEV Community

Cover image for New in EasyAdmin 4.28: New Filters, Better Autocomplete, CSP, and Smarter Actions
Javier Eguiluz
Javier Eguiluz

Posted on

New in EasyAdmin 4.28: New Filters, Better Autocomplete, CSP, and Smarter Actions

EasyAdmin 4.28 is out, and it's packed with features to improve your backends.

Clickable Rows in the Index Page

Here's something users have requested for years: clicking anywhere on a row in the index page now navigates to that entity. By default, it goes to the edit page (or falls back to detail if edit isn't available).

But you have full control:

public function configureCrud(Crud $crud): Crud
{
    return $crud
        // navigate to detail instead of edit
        ->setDefaultRowAction(Action::DETAIL)

        // use a custom action
        ->setDefaultRowAction('review')

        // define a fallback chain (first available action wins)
        ->setDefaultRowAction([Action::DETAIL, 'preview', Action::EDIT])

        // disable row clicks entirely
        ->setDefaultRowAction(null);
}
Enter fullscreen mode Exit fullscreen mode

The behavior is smart: if the configured action isn't available for a specific entity (disabled, no permission, or condition not met), that row simply won't be clickable. Clicks on checkboxes, buttons, links, or other interactive elements within the row work as expected: they don't trigger navigation.

You can set a global default in your dashboard and override it per CRUD controller:

// in your Dashboard: applies to all CRUD controllers
public function configureCrud(): Crud
{
    return Crud::new()->setDefaultRowAction(Action::DETAIL);
}

// in a specific CRUD controller: overrides the dashboard default
public function configureCrud(Crud $crud): Crud
{
    return $crud->setDefaultRowAction(Action::EDIT);
}
Enter fullscreen mode Exit fullscreen mode

Read the docs about default row actions

Content Security Policy (CSP) Support

If you've ever tried to use EasyAdmin with strict CSP headers (especially with NelmioSecurityBundle), you know the frustration: script violations everywhere.

Not anymore. EasyAdmin 4.28 automatically injects nonce attributes when the csp_nonce() Twig function is available (i.e. when NelmioSecurityBundle is installed in your application). Inline onclick handlers have been replaced with data attributes processed by JavaScript. Zero configuration required, it just works.

Thanks to Mikołaj Jeziorny for contributing this feature.

Five New Filters

Filtering by country, currency, language, locale, or timezone used to require creating custom filters. Now they're built-in:

$filters
    ->add(CountryFilter::new('country')->includeOnly(['US', 'CA', 'MX']))
    ->add(CurrencyFilter::new('currency')->preferredChoices(['USD', 'EUR']))
    ->add(TimezoneFilter::new('timezone')->forCountryCode('US'));
Enter fullscreen mode Exit fullscreen mode

All filters display localized names using Symfony's Intl component. They support multi-select, preferred choices at the top of the list, and many other options. Read the docs about the new filters.

Confirmation for Any Action

The delete action has always shown a confirmation dialog. Now you can add the same protection to any action with a single method call:

Action::new('archive', 'Archive')
    // ...
    ->askConfirmation();
Enter fullscreen mode Exit fullscreen mode

This displays a generic confirmation modal. But you can customize the message:

Action::new('publish', 'Publish')
    // ...
    ->askConfirmation('Are you sure you want to publish this article?');
Enter fullscreen mode Exit fullscreen mode

Need dynamic content? Use placeholders that get replaced automatically:

->askConfirmation(
    'Delete %entity_name% #%entity_id%? This cannot be undone.'
)
Enter fullscreen mode Exit fullscreen mode

You can also customize the confirmation button label (instead of the default "Confirm"):

->askConfirmation(
    'Publish this article to production?', 'Yes, publish it'
)
Enter fullscreen mode Exit fullscreen mode

Both parameters support TranslatableInterface objects for full i18n support. And yes, you can now disable confirmation on the delete action if you really want to (though we don't recommend it).

Preferred Choices

When you have dozens of options but users pick the same three 90% of the time, put them at the top:

ChoiceField::new('status')
    ->setChoices([/* many choices */])
    ->setPreferredChoices(['draft', 'published']);
Enter fullscreen mode Exit fullscreen mode

The preferred choices appear first, visually separated from the rest.

Read the docs about preferred choices

Autocomplete Customization

Association fields with many options use autocomplete by default. Until now, the dropdown displayed whatever __toString() returned. Now you can customize how entries are formatted.

Using a callback for simple formatting:

AssociationField::new('author')->autocomplete(
    callback: static fn (User $user) => sprintf('%s (%s)', $user->getFullName(), $user->getEmail()),
);
Enter fullscreen mode Exit fullscreen mode

Using a Twig template for rich HTML formatting:

AssociationField::new('product')->autocomplete(
    template: 'admin/fields/product/autocomplete.html.twig',
    renderAsHtml: true,
);
Enter fullscreen mode Exit fullscreen mode

The template receives the entity as the entity variable. Set renderAsHtml: true only when you trust the content (it disables XSS escaping):

{# templates/admin/fields/product/autocomplete.html.twig #}
<div class="product-option">
    <strong>{{ entity.name }}</strong>
    <span class="text-muted">({{ entity.sku }})</span>
    {% if entity.stock < 10 %}
        <span class="badge badge-danger">Low Stock</span>
    {% endif %}
</div>
Enter fullscreen mode Exit fullscreen mode

Read the docs about autocomplete() customization


✨ If you enjoyed these features and want to see more like it, consider
sponsoring the EasyAdmin project 🙌💡

Top comments (0)