Default order of records
$orderBy sets the default order of the records. It is registered as a global Eloquent scope, so it applies to the admin table and to every query in your application.
Remove the order in a query with
withoutGlobalScope('order'):
$reversed flips the direction of $orderBy, e.g. to list the oldest records first while keeping drag and drop reordering.
Number of records
Minimum
Once the minimum number of records is reached, records can not be deleted. The delete button is disabled and the server refuses the request.0 means no limit.
Maximum
Once the maximum number of records is reached, the administration hides the button for adding new records.0 means no limit. A child model with $maximum = 1 is available on the parent as a hasOne relation instead of hasMany:
app/Models/ClientsAddress.php
The maximum is applied by the administration interface. Records created by your code are not limited.
$minimum = 1 together with $maximum = 1 switches the module into single record mode.
Filtering rows in the administration
scopeAdminRows is a query scope applied to every administration request of the module: the table, the record count, opening a record, updating it, buttons and exports. Queries in the rest of the application are not affected.
app/Models/Order.php
A record outside the scope can not be opened or updated, the response is 404. When an update moves the record out of the scope, the response still contains the updated record, it disappears on the next table refresh.
scopeAdminRows($query) too, both scopes are applied.
Row responses
Columns loaded by the query
The table response contains only the fields of the admin model. A value added to the query does not reach the response until you make it visible.app/Models/Package.php
setAdminRowResponse is also the place to add accessors to the form, $this->append('full_address').
Row attributes
The serialized record can be changed before it is sent to the administration. Every method receives the attributes and must return them.app/Models/Order.php
setAdminRowsAttributes are sent in a separate $table key of the row. The table displays them while the form keeps the original values, so a formatted price does not break the price input.
For single record modules ($single, $inParent) the table is rendered as a form, so setAdminRowAttributes runs instead of setAdminRowsAttributes.
Module requests
Initial data of the module
getAdminModelInitialData sends additional data to the administration when the module is opened. Each key is available in Vue components of the module through model.getData(key).
app/Models/AttributesItem.php
Changing the module definition
adminModelRender receives the whole module definition sent to the administration (name, settings, fields, insertable, maximum, …) and must return it. It runs after model modules, which receive the data by reference (adminModelRender(&$data)).
Table requests
The table loads records withPOST /admin/api/models/{table}/rows. Parameters:
Records are ordered by
$orderBy, sorting by a column header happens in the browser.
Search
Table search
Custom column search
set{Column}AdminSearch replaces the search of a column. It is also used when the search runs in all columns. getSearchAdminColumnOperator decides how words of the query are combined.
app/Models/Product.php
Preset searches
$searches opens the table with prepared search bars. Keys are column names.
app/Models/Order.php
searches($row) method for dynamic values, e.g. the current month.
Searching in child records
When the table is searched in a selected column,search.deep also finds parent records whose child records match.
app/Models/Product.php
Child records are searched only when a column is selected in the search bar. When the child model does not have the selected column, all its columns are searched.
Encrypted fields
Values ofencrypted string, decimal and date fields are stored with a hash in the _encrypted_hashes column, so the table search finds them by the whole value, ignoring case and accents. Partial values are not found.
Disable hashes when encrypted values must not be searchable. Encrypted columns of the model are then skipped by the search.
Filter buttons
getFilterStates() adds filter buttons above the table. The selected filter applies its query, and the first state whose active closure is true is shown as a colored indicator in the row.
app/Models/OrdersItem.php
$this inside active is the listed row. More selected filters are combined, see the filter settings to allow only one.
Request scopes
The table request containsscopes, each calls a local scope of the model (or of a module) with its value. Filter buttons use them, and custom Vue components can add their own:
app/Models/Order.php
Exports
Exports generate a file from the records of the table. They are Laravel Excel export classes, PDF exports usempdf/mpdf.
app/Admin/Exports/StockExport.php
app/Models/ProductsStock.php
?debug=1 to the export URL (/admin/api/models/{table}/exports/{ExportClass}) to see the HTML output.
A question() method asks for confirmation or custom inputs before the export is generated, the same way as actions with a confirmation.
Export of selected records
An export extendingAdmin\Contracts\Exports\AdminButtonExport is rendered as a record button. It generates the file for one record, or a ZIP archive with one file per record when more records are selected.
Table download
RegisterTableExportXls in $exports to add Download excel to the standard export menu. Install phpoffice/phpspreadsheet in your application.
The export creates an .xlsx workbook from all rows matching the current search, scopes, language and parent context, without pagination. It uses the table row serialization and includes requested additional columns. Select and relation values become option names, booleans become Yes/No, HTML is removed and column headings use the table labels. Empty results produce an empty workbook.
The file uses the standard export private storage and download endpoint. Existing setSheet{Column}Attribute() and setExcelSheet() hooks still apply.