List
Description
The "List" module purpose - render list of some records from your database to work with them.
When the resolved list has no rows, Adminix renders a single No records found. table row. The empty state uses the same table width and responsive scroll container as regular records, including relation manager child lists.
Configuration
Basic example:
To add to the page List module you need paste AlexKudrya\Adminix\Modules\List\ListModule class instance as an argument to addModule or addModules method of AdminixPage object.
ListModule configuration
Full settings list:
Method | Description | |
|---|---|---|
name | Name of module, must be unique in current page.
name('users')
| Required |
title | Title on the top of the module
title('USERS')
| Optional |
pagination | Number of items per page. To disable pagination must be equal to 0 or not exist.
pagination(20)
| Optional |
dataSource | Source of data for List, can be an
dataSource(\App\Models\User::class)
| Required |
withDeleted | Determines render or not deleted records (working with models with included By default, is not active
withDeleted()
| Optional |
hiddenOnIndex / hideOnIndex | Removes the field from the server-rendered index table and from inline-edit writable field resolution. Use this for server-side list visibility, not for browser-only column preferences.
hiddenOnIndex()
hideOnIndex()
| Optional |
editable | Determines possibility to edit records directly in the List. Editable possibility for every field determines in his personal config. By default, is not active
editable(),
| Optional |
primaryKey | Primary key in source table. Used for editable mode. Usually it is "id"
primaryKey('id')
| Required if editable mode is enabled |
criteria | Database
criteria([
['is_admin', '=', false]
])
Or you can paste parameter from route:
criteria([
['user_id', '=', 'param:1']
])
For example, for Module/query criteria are normalized through Adminix's shared criteria contract. Supported operators are | Optional |
resource | Laravel
resource(\App\Http\Resources\UserAdminResource::class)
| Optional |
addLens addLenses | Add server-defined saved views for the current list. Each lens can apply extra criteria, lens-specific default sorting, and explicit
addLenses(
ListLens::name('active')
->title('Active')
->criteria(['status' => 'active']),
ListLens::name('trash')
->title('Trash')
->withDeleted()
)
Detailed settings described below. #Lenses | Optional |
addField addFields | Methods by which you can add fields to List for displaying. Arguments can be only Detailed here #Fields
addField(
ListField::name('Name')
->field('name')
->type(ListFieldTypeEnum::STRING)
->sortable()
)
| Required |
rowDetails | Attach a server-declared expandable detail panel to each row. The panel reuses
rowDetails(
ListRowDetails::make('Details')
->columns(2)
->addFields(
DetailField::make('Status', 'status')->badge('#754195'),
DetailField::make('Payload', 'metadata')->json()
)
)
Detailed settings described below. #Row details | Optional |
search | Render "Search" input on the top of module. Argument -
search(
ListSearch::searchFields(['name', 'email'])
->placeholder('Search users')
)
Detailed settings described below. #Searching | Optional |
addFilter addFilters | Methods by which you can add filters for current List. Arguments can be only several classes instances:
->addFilters(
ListFilter::field('role_id')
->name('Role')
->src(
InputSelectSrc::nameField('name')
->valueField('id')
->dataSource(UserRole::class)
),
ListDateRangeFilter::field('created_at')
->name('Registration time')
->withTime()
)
Detailed settings described below. #Filters | Optional |
columnVisibility | Add a
columnVisibility()
Detailed settings described below. #Column visibility | Optional |
densitySwitcher | Add table density controls to the list settings menu. The switcher is browser-only and stores compact/comfortable state by list name.
densitySwitcher()
Detailed settings described below. #Density and sticky table controls | Optional |
stickyHeader | Keep the table header visible while scrolling inside the table container.
stickyHeader()
Detailed settings described below. #Density and sticky table controls | Optional |
stickyActions | Keep the row action column visible while scrolling wide tables horizontally. It uses the existing row action buttons/forms/modal togglers.
stickyActions()
Detailed settings described below. #Density and sticky table controls | Optional |
rowActionsDropdown | Render row actions behind one vertical three-dots dropdown button instead of inline buttons. This is only a presentation option; row action definitions, criteria, methods, params, CSRF forms, tooltips, and modal togglers stay server-defined.
rowActionsDropdown()
Detailed settings described below. #Actions | Optional |
resetControls | Add an opt-in "Reset view" action to the list settings menu for the current list state. The control removes current list search, filters, sorting, active lens, and pagination from the URL.
resetControls()
Detailed settings described below. #Reset controls | Optional |
addAction addActions | Methods by which you can add action buttons (Links) for every item in current List module. Arguments can be only several classes instances:
addAction(
AdminixLinkModule::name('user_details')
->title('DETAILS')
->icon('bi bi-pencil')
->uri(UserPage::URI)
->params(['record:id']),
)
Detailed settings described below. #Actions | Optional |
addBulkAction addBulkActions | Methods by which you can add server-side batch actions for selected rows in current List module. Arguments can be only
addBulkAction(
BulkAction::make('mark_paid')
->title('Mark paid')
->icon('bi bi-check2')
->confirm('Mark selected orders as paid?')
->handler(MarkOrdersPaidAction::class)
)
Detailed settings described below. #Bulk actions | Optional |
sorting | Basic sorting for records in current List module. Argument can be only Example:
sorting(
Sorting::field('id')
->direction('asc')
)
| Optional |
newItemLink | Setting for "New Item" button rendered between Title and List, near to Search input. When a list has both create and search controls, Adminix keeps them grouped on the left side of the list toolbar. Format is similar to Adminix Link module.
newItemLink(
AdminixLinkModule::name('new_user_btn')
->title('NEW USER')
->icon('bi bi-person-fill-add')
->uri(NewUserPage::URI)
)
Detailed here #New item link | Optional |
Lenses
Lenses are server-defined saved views for ListModule. They are useful for common list presets such as Active, Drafts, Deleted, VIP, or Needs review.
The active lens is selected by the query key lens-{moduleName}. Adminix resolves this value only against lenses configured in PHP. Unknown lens names are ignored and the default list is rendered.
Lens criteria are applied after base ListModule::criteria() and before user filters, search, and sorting. Lens filters are defaults for configured list filters. Use the filter field as the key:
Result: when the URL contains lens-users=needs-review and does not contain filter-users-status, Adminix applies status = pending and shows the filter as selected. If the URL already contains filter-users-status, the request value wins and the lens default is not used. Date range defaults can use a nested from/to map or flat keys such as created_at-from. Lens sorting is a default sorting only: if the request contains a valid sort-{module}-{field} parameter, the user-selected sorting wins. Pagination links keep the active lens query parameter.
Use base criteria() for mandatory tenant/user scoping. Use lenses only for alternate server-owned views inside that scope.
Fields
Fields is an array, of fields to be rendered in the List.
To add Field to the List module you need paste AlexKudrya\Adminix\Modules\List\ListField class instance as an argument to addField or addFields method of ListModule object.
Field Presentation
ListField supports the same presentation helpers as resource fields for table columns and inline-edit controls. These helpers only change server-rendered UI; they do not change query criteria, sorting, writable fields, or export behavior.
Available helpers:
placeholder($text)sets inline-edit input placeholders and async select search placeholders;help($text)renders escaped helper text in the table header;width('narrow'|'medium'|'wide'|'full')adds safe width classes to the table header and cells;narrowWidth(),mediumWidth(),wideWidth(), andfullWidth()are named width shortcuts;alignment('start'|'center'|'end')controls table header/cell alignment;left,middle, andrightare normalized aliases;alignStart(),alignCenter(), andalignEnd()are named alignment shortcuts.
Invalid width/alignment values are ignored. Use hiddenOnIndex(), hideable(), defaultHidden(), editable(), and exportable() for behavior; presentation helpers are not access-control tools.
Row details
Use ListRowDetails when a list needs a compact primary row plus expandable read-only metadata. Adminix renders one toggle column and a hidden detail row for every visible record. The detail panel is prepared from the same server-side list datasource, base criteria, active lens, filters, search, sorting, pagination, and optional relation scope used for the rendered table.
ListRowDetails supports:
make($title = null)/title()for an optional detail heading;columns(1..4)for the read-only field grid;addField()/addFields()withDetailFieldor anotherResourceFieldsubclass;expanded()to render all detail rows initially open, otherwise they are collapsed and toggled with JavaScript.
Row details do not add a write endpoint and do not trust browser-owned datasource, criteria, field names, or primary keys. Password fields are rendered without stored values, matching resource/detail password safety. Keep sensitive tenant, owner, credential, and internal audit columns out of row details unless they are intentionally visible to the admin user.
Badge / Status Field
Use badge() or status() when a list column should show a compact visual state instead of raw text. Badge fields are display-only: even on editable lists, ListFieldTypeEnum::BADGE is excluded from inline edit writes.
badge('#754195') applies one color to all values. badgeMap() accepts the same map as status(). When a value is not mapped, Adminix renders the scalar value with the field default badge color.
Money / Currency Field
Use money($currency = 'USD', $decimals = 2) for amount columns that should render as tabular currency values. On editable lists, money fields remain writable number inputs and use a decimal step derived from $decimals.
Result: read-only cells render values such as EUR 1,234.50; editable cells render a number input with step="0.01".
Color Field
Use color() for color values stored as CSS color strings, commonly hex values such as #754195. Read-only list cells render a swatch and the stored value; editable list cells render a native color picker.
Slug Field
Use slug() for columns that store URL-friendly slugs. List slug fields render like scalar text and can still be sortable when the underlying database column supports it.
If the list is editable and the field is marked editable(), Adminix renders a normal text input. Keep slug validation and uniqueness server-side in the resource or inline-edit validation rules.
Markdown Field
Use markdown() for columns that store markdown text. Read-only list cells render a compact safe preview: raw HTML is escaped, while simple markdown links, **strong**, *emphasis*, inline code, and line breaks are rendered. Editable list cells render a textarea and submit the raw markdown value.
Markdown columns are usually long, so generated smart resources mark them defaultHidden() and do not make them sortable. Keep validation and content policy server-side.
JSON / Code Field
Use json() for JSON payload columns. Read-only list cells render a compact pretty-printed preview, and editable list cells render a monospace textarea with progressive JSON syntax feedback. The helper adds the Laravel json validation rule; if JavaScript is unavailable, inline edit still submits a normal textarea value to server validation.
Generated smart resources mark JSON list columns defaultHidden() and do not make them sortable. Keep schema-specific validation in the consuming application.
Key-Value Field
Use keyValue() for object-like JSON columns such as metadata, settings, options, or attributes. Read-only list cells render compact key/value rows. Editable list cells render the same progressive key/value editor as resource forms and submit a single JSON object field.
The helper adds the Laravel json validation rule. Generated smart resources mark key-value list columns defaultHidden() and do not make them sortable.
Date Range Field
Use dateRange() for JSON values shaped like {"from":"2026-01-01","to":"2026-01-31"}. Read-only list cells render a compact date-range label, and editable list cells render the same progressive two-date editor as resource forms.
The helper adds the Laravel json validation rule. Keep ordering and filtering on dedicated date columns when the database needs efficient range queries; this field is for displaying or editing a persisted range value.
Timezone Field
Use timezone() for columns that store IANA timezone identifiers. Read-only list cells render the stored identifier, and editable list cells render the same server-declared timezone select as resource forms.
The helper adds Laravel's timezone validation rule for editable list submissions. Use application validation when timezone changes must be restricted by tenant, user, or business context.
Tags Field
Use tags($separator = ',') for tag-list columns. Read-only list cells render chips. Editable list cells render a normal text input with a progressive chip preview and submit the separator-delimited string.
The formatter accepts separator-delimited strings, JSON array strings, and array values. Generated smart resources mark tag columns defaultHidden() and do not make them sortable.
Example:
ListField configurations
Method | Description | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
name | Title of the field displayed on the top of table (inside
name('Role')
| Required | ||||||||
type | Type of rendered field, can be provided only by Available types for rendered field:
It determines data format to render, and type of input for Example:
type(ListFieldTypeEnum::SELECT)
| Required | ||||||||
field | Name of field in database or resource (if resource was provided).
field('role_id')
| Required | ||||||||
sortable | Determines the sorting possibility for current field. Can not be used to fields which provided by resource, and not exist in database table, or his name was modified. By default, is not enabled.
sortable()
| Optional | ||||||||
hideable | Allows the field to appear in the
hideable()
| Optional | ||||||||
defaultHidden | Allows the field to appear in the
defaultHidden()
| Optional | ||||||||
editable | Determines the editable possibility for current field. Can not be used to fields which provided by resource, and not exist in database table, or his name was modified. This will not be working if in To working correctly requires primary key (usually it is "id" field) in this fields list (can be By default, is not enabled.
editable()
| Optional | ||||||||
src | Required for fields with type For example, Argument can be only Example:
ListField::name('Role')
->field('role_id')
->type(ListFieldTypeEnum::SELECT)
->editable()
->src(
InputSelectSrc::nameField('name')
->valueField('id')
->dataSource(Role::class)
)
| |||||||||
asyncSrc | Use Example:
use AlexKudrya\Adminix\Modules\AsyncInputSelectSrc;
ListField::name('Author')
->field('author_id')
->type(ListFieldTypeEnum::SELECT)
->editable()
->asyncSrc(
AsyncInputSelectSrc::dataSource(User::class)
->nameField('name')
->valueField('id')
->searchFields(['name', 'email'])
->criteria(['active' => true])
->minLength(2)
->limit(20)
->placeholder('Search authors')
);
Result: editable rows search remote options with For read-only list cells, async fields render the stored value because Adminix intentionally does not eager-load labels for all rows. Use synchronous | |||||||||
addSelectRecords | Required for fields with type Arguments can be only Example:
ListField::name('Role')
->field('role_id')
->type(ListFieldTypeEnum::SELECT)
->editable()
->addSelectRecords(
SelectRecord::name('Admin')->value(1),
SelectRecord::name('Manager')->value(2),
SelectRecord::name('Seller')->value(3),
SelectRecord::name('Guest')->value(4),
)
...
|
Column visibility
columnVisibility() adds a Columns section to the compact list settings dropdown for the current ListModule. Only fields marked with hideable() or defaultHidden() are included in that section. The list settings dropdown grows to its content height and only uses vertical scrolling when the menu would exceed the viewport. On narrower desktop viewports, the list settings button shifts left only when its screen position vertically overlaps the fixed shell notification bell. Column toggles, density options, reset, and CSV export actions share the same menu item sizing, spacing, rounded corners, and hover treatment. Column toggles are rendered as switch controls, matching boolean field controls elsewhere in Adminix.
Result: Adminix shows a gear-icon settings button as a root-level absolute control aligned to the list title area. The control does not reserve toolbar or filter space; when a list has no title, it stays inside the list root without adding an empty row. The Customer column is visible by default and can be hidden by the user. The Internal note column is hidden by default and can be shown from the same settings menu. The hidden id field and service columns for inline edit or row actions are not controlled by column visibility.
Column visibility is a browser-only presentation setting. It is stored in local storage by list name and does not change request keys, datasource, criteria, filters, sorting, row actions, authorization, or export scope. For server-side list visibility, use ListField::hiddenOnIndex()/hideOnIndex(). Hidden-on-index fields are not rendered in the table and are not writable through inline edit.
Density and sticky table controls
densitySwitcher(), stickyHeader(), and stickyActions() are opt-in presentation helpers for wide or frequently used tables.
Result: Adminix renders Comfortable and Compact density choices inside the gear-icon list settings menu. The selected density is stored in browser local storage by list name. Compact density reduces table cell padding plus inline row controls such as editable inputs, selects, row action buttons, switches, date-range/key-value editors, async selects, and row images. Inline controls use a 32px minimum height, row images cap at 38px, cells align content vertically in the middle, and action button icons keep the normal UI-kit gap from text. stickyHeader() keeps table headers visible inside the scroll container. stickyActions() keeps the existing final service column visible while the table fits the available width. When a list table is wider than the available viewport, Adminix preserves the table's content width, moves the service column into the horizontal scroll flow, and uses horizontal scrolling instead of compressing or overlapping right-side columns into data cells.
These controls do not create a new action layer. Existing addAction()/addActions() links, non-GET forms, confirm prompts, tooltips, modal togglers, and record:*/param:* route parameters continue to render through the same row action contract. If the list also uses rowActionsDropdown(), stickyActions() keeps the dropdown trigger in the same service column.
CSV export
exportCsv() adds an Export CSV action to the list settings menu for the current ListModule. CSV export is disabled by default and must be enabled per list.
Result: Adminix shows an Export CSV action inside the gear-icon list settings menu. The endpoint applies the same server-side datasource, criteria, active lens, filters, search, and sorting as the list. The current pagination page is ignored, and export rows are capped by the configured limit. The default limit is 10000.
The browser cannot choose a datasource or arbitrary columns for CSV export. Adminix signs the current page params when rendering the export link so param:* criteria use the same route context as the visible list. ListFieldTypeEnum::HIDDEN fields are excluded by default. Use ListField::exportable() only for hidden fields that are safe to include in the CSV. Fields hidden with hiddenOnIndex() are also excluded unless they are explicitly marked exportable(). Row actions, inline edit controls, service columns, and UI-only column visibility are not exported.
Bulk actions
Bulk actions are opt-in server-side actions for selected rows in a ListModule. They render a checkbox column, Select all current page checkbox, action dropdown, selected count, and submit button above the table.
Result: Adminix shows bulk controls above the list. The button stays disabled until the user selects at least one current-page row and one configured action. When confirm() is configured, the browser shows that confirmation before submitting. The web endpoint redirects back with a success or error toast, or returns a direct Response when the handler returns one.
BulkAction settings:
name()is the stable server-side action key submitted by the browser.title()is the dropdown label.icon()stores an optional Bootstrap icon class for package consumers and future renderers.tooltip()stores optional helper text for package consumers and future renderers.color()stores an optionalColorsEnumvalue or CSS color string.destructive()marks dangerous actions for custom renderers and future UI states.confirm()sets an optional submit confirmation message.criteria()stores optional action visibility criteria metadata; execution still uses the selected row scope.addField()/addFields()declare input fields shown before the selected bulk action is submitted.handler()accepts a callable, object, or class string. ImplementBulkActionHandlerInterfacefor reusable actions.authorizeUsing()/authorization()accepts a boolean, callable, object withauthorize(), or class string.batchLimit()caps selected scalar IDs before the handler runs. Default is1000.queued('Message')dispatches the handler through Laravel queues after the normal server-side scope and authorization checks.progressTrigger()starts a matchingProgressBarModuletrigger when the selected action is submitted.onConnection()andonQueue()optionally select the Laravel queue transport for queued bulk actions.actionMetadata()returns the shared Actions metadata DTO.
BulkActionRequest gives handlers:
module()andaction()from server-side configuration;requestedIds()from the request after scalar normalization;selectedIds()after applying the current list scope;query()already scoped to selected records;primaryKey()from the list module;httpRequest()for request/session context when needed.fields()andfield($name, $default = null)for server-declared action field values.
Action fields are documented in Actions. They are submitted as adminix_action_fields[...], but Adminix only passes keys declared on the selected server-side BulkAction to the handler.
Handlers can return:
BulkActionResult::success('Message');BulkActionResult::error('Message');BulkActionResult::validation(['field' => ['Message']]);BulkActionResult::redirect('/adminix/orders');BulkActionResult::openInNewTab('/adminix/orders/export.csv');BulkActionResult::modal('Title', 'Body');BulkActionResult::download($response)or a Symfony/LaravelResponsefor downloadable/custom responses.
Typed action responses are documented in Actions. Queued actions are documented in Actions.
The endpoint resolves page, module, relation context, and action from server-side module configuration. The browser submits only selected IDs and action name. Datasource, primary key, criteria, active lens, filters, search, sorting, relation parent scope, and page params are resolved server-side. IDs outside the current criteria/search/filter/relation scope are ignored; if no selected ID remains in scope, the request fails with a controlled validation error. After a handler returns a normalized result, Adminix dispatches BulkActionExecuted and passes the scope-filtered selected IDs in audit metadata. See Audit for recorder and listener examples.
Bulk actions do not replace row actions. Existing addAction()/addActions() links, non-GET row forms, modal togglers, confirm prompts, tooltips, and record:* params remain the row action contract.
Searching
Determines possibility to make full-text search in source table.
Example:
Method | Description | |
|---|---|---|
searchFields | An array of fields which involved in the search process. The more fields, the slower but more accurate the search. Every field must be existed in main database table
searchFields(['name', 'email'])
| Required |
placeholder | A placeholder for Search
placeholder('Search users')
| Optional |
Filters
Add filters to the top of the module, near to search input. Provides the ability to filter the list by specific fields.
There are several types of filters available:
ListFilter -
AlexKudrya\Adminix\Modules\List\ListFilterListDateFilter -
AlexKudrya\Adminix\Modules\List\ListDateFilterListDateRangeFilter -
AlexKudrya\Adminix\Modules\List\ListDateRangeFilter
ListFilter
Basic filter - <select/> input with defined options
Example:
1 usage variant - get records for filter from DB table by Eloquent model or table name, and took nameField as displayable name and valueField as value for filtering
Or 2 usage variant - get records for filter from DB table by Eloquent model or table name by SELECT DISTINCT ... query
Or 3 usage variant - set records for filter manually as list of ListFilterRecord objects
Method | Description | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
name | Title of the filter
name('Role')
| Required | ||||||||
field | Name of the field used for filtering. Field must be existed in base database table
field('role_id')
| Required | ||||||||
src | Required if filter_records is empty. Has a format similar to
src(
InputSelectSrc::nameField('name')
->valueField('id')
->dataSource(\App\Models\Role::class)
),
| Required if no filterRecords() and no distinct() | ||||||||
distinct | Field and table for `SELECT DISTINCT` selection
distinct('role', \App\Models\User::class),
| **Required** if no **src()** and no **filterRecords()** | ||||||||
filterRecords | Required if src is empty. It is an
addFilterRecords(
ListFilterRecord::name('Client')->value(1),
ListFilterRecord::name('Guest')->value(2),
ListFilterRecord::name('Manager')->value(3),
ListFilterRecord::name('Admin')->value(4),
)
| Required if no src() and no distinct() |
ListDateFilter
Date filter - allows you to select records within a selected date.
Example:
Method | Description | |
|---|---|---|
field | Name of the field used for filtering. Field must have
field('created_at')
| Required |
name | Title of the filter
name('Registration date')
| Required |
ListDateRangeFilter
Date range filter - allows you to select records within a date range.
Example:
Method | Description | |
|---|---|---|
field | Name of the field used for filtering. Field must have
field('created_at')
| Required |
name | Title of the filter
name('Registration date')
| Required |
withTime | Determines whether the filter will filter by time or only by dates. By default, filter only by date, without time.
withTime()
| Optional |
filterFrom | Define "From" input. If set By default, it is enabled.
filterFrom(false)
| Optional |
filterTo | Define "To" input. If set By default, it is enabled.
filterTo(false)
| Optional |
Reset controls
resetControls() adds a Reset view action to the list settings menu for the current ListModule. It is disabled until the current URL or browser storage contains state for that list.
Result: when the URL contains keys such as search-orders, filter-orders-status, sort-orders-created_at, lens-orders, or page, Adminix shows an enabled Reset view action inside the gear-icon list settings menu. The same action is enabled when browser-only view state exists for the list, such as hidden/shown columns or compact density. Clicking it returns to the same page without current-list URL state and clears current-list browser view state. Unrelated query parameters and another list module's view state are preserved.
This is a presentation and URL-state convenience only. It does not create a new server-side action endpoint and does not change list filters, row actions, datasource, or authorization behavior.
Mobile behavior
ListModule keeps the same PHP configuration and request contract on mobile. Search, lenses, filters, sorting, pagination, editable rows, row actions, and modal togglers still use the same module name and server-side configuration.
Example configuration:
Result:
desktop renders filters inline above the table;
narrow screens show a
Filtersbutton with an active-filter count;the button opens a drawer containing the same
ListFilter,ListDateFilter, andListDateRangeFiltercontrols;changing a filter still writes the same
filter-{moduleName}-{field}query key and resets pagination;wide tables scroll horizontally inside the table area, not across the whole Adminix shell;
row actions remain the existing buttons/forms/modal togglers, including route params, CSRF methods, confirm text, icons, and tooltips.
The mobile drawer is a presentation wrapper only. Do not add browser-owned datasource, action, or filter metadata; continue to configure lists from PHP classes.
Actions
"Actions" is an array of control buttons for every single record, to do some actions, such as "open", "edit", "delete", or wherever else you need.
Example:
To add Action buttons to List module you need paste AlexKudrya\Adminix\Modules\Link\AdminixLinkModule or AlexKudrya\Adminix\Modules\Link\LinkModule class instances as an argument to addAction or addActions method of AdminixPage object.
Action buttons syntax is similar to Link module
By default, Adminix renders row actions inline in the final service column. For dense tables with many row controls, call rowActionsDropdown() on the same ListModule to render one compact vertical three-dots button per row. Clicking it opens a small contextual dropdown next to the trigger and shows the same configured actions inside the menu.
Result: every row keeps a single bi-three-dots-vertical trigger in the action column. The dropdown contains the existing GET links, POST/PUT/PATCH/DELETE forms with CSRF and confirm prompts, and modal togglers. If an action has an icon but no title, the dropdown uses the action name() as a text label so the menu remains readable. Rows where criteria() hides all actions still render an empty service cell to keep the table columns aligned.
rowActionsDropdown() is presentation-only. It does not change action authorization, criteria evaluation, route parameter substitution, signed modal relation context, request payloads, datasource, or persistence behavior.
Method | Description | |
|---|---|---|
name | Title which will be displayed on the button
name('EDIT')
| Optional |
uri | In case
uri(UserPage::URI)
In case
uri('edit_user')
| Required |
icon | Icon class name from Bootsrap icons Example: to generate in the Link an icon
icon('bi bi-people-fill')
| Optional |
method | Type of HTTP request, can be provided only by In case In case By default, it is equal to
method(HttpMethodsEnum::POST)
| Required if not GET |
params | Technically it is optional directive, but It is list of parameters which you added to your action (usually it is "id"). When Parameters adds to your link like this: / Example:
params(['record:id'])
For record with id = 123 action link will be | Required |
criteria | Determines display or not this action button for current record. For example if you need display action button only for users without admin status, you can do it like this:
criteria([
['is_admin', '==', false]
])
or
criteria([
['deleted_at', '!=', null]
])
Action visibility criteria are evaluated against the rendered list row, not the database query builder. For row actions this directive intentionally supports only | Optional |
New item link
Usually, in the admin panels, lists have the ability to add new records, and the New resource module is used for this. In order to display a link to a page with such a module in the correct place in the "list" module, there is this directive
Format is similar to Link module or Actions
Example:
or
Appearance examples
Here is example of List without editable mode:

Here is example of List with editable mode:
