This section describes how to add actions to tables such as edit and delete or CSV download.
Register Hook
In tables you can create actions and register them in JavaScript using the registerHook method.
1. JavaScript
For example:
registerHook('table-action-table_posts-edit', function (id) {
window.location.href = milk_url + '?page=posts&action=edit&id=' + id;
return false;
});
registerHook('table-action-table_posts-delete', function (id) {
return confirm('Delete this post?');
});
The registerHook receives as the first parameter the string 'table-action-{table_id}-{action}'.
It returns a boolean. If true, it makes the fetch call and updates the table; if false, it doesn't make the fetch call. In this example, edit redirects to the edit page and delete makes the fetch call and updates the table.
2. Backend PHP
In the router, the delete calls the same function that is called when generating the table. If you are extending the AbstractController, you just need to write:
$this->callTableAction($table_id, 'delete', 'table_action_delete');
and then create a new function
protected function tableActionDelete($id, $request) {
if ($this->model->delete($id)) {
return true;
} else {
MessagesHandler::addError($this->model->getLastError());
return false;
}
}
For edit, instead, it redirects to a new page so it's handled normally in the router by writing a new action_edit function
protected function actionEdit() {
$id = _absint($_REQUEST['id'] ?? 0);
$data = $this->model->getByIdForEdit($id, Route::getSessionData());
Response::themePage('default', __DIR__ . '/Views/edit.page.php', ['id' => _absint($_REQUEST['id'] ?? 0), 'data' => $data, 'page' => $this->page, 'url_success'=>'?page='.$this->page, 'action_save'=>'save']);
}
CSV Export with Table Filters
Tutorial for implementing CSV download of filtered table data using the table_action system.
1. Export Button Setup
Open the list.page.php file and add the export button in the title section:
'btns' => [ ['title'=>'Add New', 'color'=>'primary', 'link'=>'?page='.$page.'&action=edit'], ['title'=>'Export CSV', 'color'=>'success', 'class'=>'js-export-csv', 'link'=>'#'] ]
2. JavaScript - Export Function
Create the JavaScript function to handle the download:
// Initialize export button
// Initialize export button
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('.js-export-csv').addEventListener('click', function() {
exportData();
});
});
/**
* Export table data to CSV
*/
function exportData() {
const btnExport = document.querySelector('.js-export-csv');
if (btnExport.classList.contains('disabled')) {
return;
}
btnExport.classList.add('disabled');
// Get table component
const table = getComponent('table_posts');
table.setActionFields('export-csv');
table.setPage(1);
// Submit form to trigger download
const form = table.getForm();
form.submit();
// User feedback
window.toasts.show();
window.toasts.body('Export started, download will begin shortly...', 'primary');
// Re-enable button
setTimeout(() => {
btnExport.classList.remove('disabled');
window.toasts.hide();
}, 3000);
}
3. Backend PHP
In the router, add the logic to handle the export before HTML generation:
protected function actionHome() {
// At the end of the function before output_table_response add:
// Table form parameters are of the type {table_id}[param]. So to get them easily you can use the get_request_params function inside the AbstractController class
$request = $this->getRequestParams($table_id);
if (isset($request['table_action']) && $request['table_action'] == 'export-csv') {
$this->exportCsv($modellist_data['rows']);
return;
}
}
private function exportCsv($rows) {
$timestamp = date('Y-m-d_H-i-s');
$filename = "posts_export_{$timestamp}.csv";
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
$output = fopen('php://output', 'w');
// Headers
fputcsv($output, ['ID', 'Title', 'Author', 'Status', 'Created'], ',', '"', '\\');
// Data
foreach ($rows as $row) {
fputcsv($output, [
$row->id ?? '',
$row->title ?? '',
$row->author ?? '',
$row->status ?? '',
(is_a($row->created_at, 'DateTime') ? $row->created_at->format('Y-m-d H:i:s') : $row->created_at) ?? ''
], ',', '"', '\\');
}
fclose($output);
exit;
}