Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Currently the only way to have bulk operation support for your entity lists is to use Views. There are various reasons to use regular list builders instead of Views, but that currently means that you cannot have bulk operations.
Proposed resolution
Let's add a list builder with bulk operation support!
Comment | File | Size | Author |
---|---|---|---|
#5 | 3018218-5.patch | 20.07 KB | idebr |
| |||
#5 | interdiff-4-5.txt | 1.63 KB | idebr |
Comments
Comment #2
tstoecklerHere we go.
The code is blatantly stolen from Views'
BulkForm
. Although by using#tableselect
, we can avoid a lot of manual logic, in particular the custom row keys.Like Views, this builds on action config entities, not the action plugins themselves. Those are a bit weird in their implementation, so I'm not opposed to finding a way to use the action plugins directly, but I thought this might be the least controversial way to get something like this done. It is also in-line with the pattern that generally the Views-based admin lists sort of "progressively enhance" the list builders in that any operation shown by the list builder provided here will also be available in Views.
This also comes with some tests for the "delete", "publish", and "unpublish" actions which nicely covers both actions with and without redirects. Because, weirdly, there is no way for unpublished entities without owners to be viewed by anyone without the admin permission I used the enhanced entity with owner in the test, so I could make use of the
view own unpublished *
permission.Comment #4
tstoecklerOK, here's an easier way to test that we're on the collection that doesn't assert the actual URL.
Comment #5
idebr CreditAttribution: idebr at ezCompany commentedThe patch in #4 works great, many thanks!
I have made a few changes:
$action->execute()
with$action->getPlugin()->executeMultiple()
in line with the suggestion in #3017214-14: \Drupal\system\Entity\Action::execute() is missing from ActionConfigEntityInterface.Comment #7
bojanz CreditAttribution: bojanz at Centarro commentedRemoved the odd @throws lines from the test, and fixed a few more phpcs violations.
Thank you!
Comment #9
mvantuch CreditAttribution: mvantuch as a volunteer commentedI've just tried using the BulkFormEntityListBuilder as a base class for my list builder but got heaps of errors as:
User error: "id" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).
What seems to be the issue is BulkFormEntityListBuilder:128 where instead of
$form[$this->entitiesKey][$entity->id()] = $this->buildRow($entity);
should in my opinion be:
$form[$this->entitiesKey]['#rows'][$entity->id()] = $this->buildRow($entity);
That said... if I do that I lose the checkboxes in the first column.
Comment #10
rahulkhandelwal1990 CreditAttribution: rahulkhandelwal1990 commented$form[$this->entitiesKey]['#options'][$entity->id()] = $this->buildRow($entity);
this will resolve checkbox disappear problem
Comment #11
djg_tram CreditAttribution: djg_tram commentedThe solution is slightly different:
#type tableselect
, nottable
. No need to attach the library manually.#options
as you suggested at the end.#weight
of 2 for the table and 1 for the header is advisable to get the same order as usual.Caveat: it ruins the pager functionality by adding an extra one. The reason for this is render() calling load() and that, in turn, calling getEntityIds(). The pager gets added twice. I would call the form unconditionally instead: