How to Add Mass Actions to Datatable
In QuickAdminPanel tables, you can tick the checkbox on every row, and then click Delete Selected:

That's the only "mass action" available. But you can create more, pretty easily.
You just need to repeat a block of code from index.blade.php file.
Currently, in resources/views/admin/courses/index.blade.php we have this JavaScript code for Delete selected button:
@can('course_delete')
let deleteButtonTrans = '{{ trans('global.datatables.delete') }}'
let deleteButton = {
text: deleteButtonTrans,
url: "{{ route('admin.courses.massDestroy') }}",
className: 'btn-danger',
action: function (e, dt, node, config) {
var ids = $.map(dt.rows({ selected: true }).nodes(), function (entry) {
return $(entry).data('entry-id')
});
if (ids.length === 0) {
alert('{{ trans('global.datatables.zero_selected') }}')
return
}
if (confirm('{{ trans('global.areYouSure') }}')) {
$.ajax({
headers: {'x-csrf-token': _token},
method: 'POST',
url: config.url,
data: { ids: ids, _method: 'DELETE' }})
.done(function () { location.reload() })
}
}
}
dtButtons.push(deleteButton)
@endcan
Let's break it down - what is happening here:
- 1.Checking @can('course_delete') for permission for this button - read more about roles/permissions here.
- 2.Button label comes from translations - see trans() method
- 3.We need to assign the URL - what should happen after the click, so we specify route('admin.courses.massDestroy')
- 4.We choose button class - btn-danger
- 5.We specify the action: first we get the list of record IDs (every row has <tr data-entry-id="xxx">), if that list is empty - we throw error alert that no rows are selected
- 6.We ask for confirmation - do you want to delete selected record?
- 7.If it's confirmed, we're making AJAX request to the URL we specified in Step 3, and then reload the whole page
That URL is specified in routes/web.php:
Route::delete('courses/destroy', 'CoursesController@massDestroy')
->name('courses.massDestroy');
Finally, here's how it works in app/Http/Controllers/Admin/CoursesController.php:
public function massDestroy(MassDestroyCourseRequest $request)
{
Course::whereIn('id', request('ids'))->delete();
return response(null, Response::HTTP_NO_CONTENT);
}
For example, let's add another button Publish which will mass-publish the Courses from the table above.
We almost copy-paste the index.blade.php block to a new one, just below the old one:
let publishButtonTrans = 'Publish'
let publishButton = {
text: publishButtonTrans,
url: "{{ route('admin.courses.massPublish') }}",
className: 'btn-warning',
action: function (e, dt, node, config) {
var ids = $.map(dt.rows({ selected: true }).nodes(), function (entry) {
return $(entry).data('entry-id')
});
if (ids.length === 0) {
alert('{{ trans('global.datatables.zero_selected') }}')
return
}
if (confirm('{{ trans('global.areYouSure') }}')) {
$.ajax({
headers: {'x-csrf-token': _token},
method: 'POST',
url: config.url,
data: { ids: ids }})
.done(function () { location.reload() })
}
}
}
dtButtons.push(publishButton)
What I've changed here:
- Button Label: publishButtonTrans = 'Publish' (or you can use translations, too)
- Different URL: route('admin.courses.massPublish') - we will create it in a minute
- Button Class: instead of btn-danger, I specified btn-warning
- AJAX Method: instead of 'DELETE' I use simple 'POST'
Notice: if you're using AJAX Datatables module, you need to populate the ids array a bit differently:
var ids = $.map(dt.rows({ selected: true }).nodes(), function (entry) {
return entry.id // instead of return $(entry).data('entry-id')
});
And, that's it! We have a button:

To make that button work, we specify the URL in routes/web.php:
Route::post('courses/publish', 'CoursesController@massPublish')
->name('courses.massPublish');
Notice: that Route should come before the resource line of Route::resource() for the same Controller, otherwise it may conflict with Resourceful methods and be overridden.
Finally, we implement that massPublish in app/Http/Controllers/Admin/CoursesController.php - almost identical to massDestroy above:
public function massPublish(Request $request)
{
Course::whereIn('id', request('ids'))->update(['is_published' => 1]);
return response(null, Response::HTTP_NO_CONTENT);
}
That's it, you have you mass-action!