I am using the yajra laravel datatables package.
I'm trying to figure out how I can refactor this little bit of controller code to an individual class (UsersDataTable) which I am using method injection to make accessible. This class extends the base DataTable class but I have not added any additional functionality to this class yet. This is what I need assistance undertanding.
public function index(Request $request, UsersDataTable $table, UserFilters $requestFilter)
{
$this->authorize('viewList', User::class);
if ($request->ajax()) {
$query = User::with('employment');
$requestFilter->apply($query);
return $table->eloquent($query)
->addColumn('action', 'users.partials.action-cell')
->filterColumn('name', function ($query, $keyword) {
$sql = "CONCAT(users.first_name, ' ', users.last_name) like ?";
$query->whereRaw($sql, ["%{$keyword}%"]);
})
->filterColumn('id', function ($query, $keyword) {
$query->where($query->qualifyColumn('id'), $keyword);
})
->toJson();
}
return view('users.index');
}
<?php
namespace App\DataTables;
use Yajra\DataTables\DataTables;
class UsersDataTable extends DataTables
{
}
<!--begin: Datatable -->
<table id="users_table" data-table="users.index" class="table table-hover"></table>
const table = $('[data-table="users.index"]');
// begin first table
table.DataTable({
ajax: {
url: window.location.href,
data(params) {
params.status = filterData.status;
params.started_at = filterData.started_at;
},
error: function(xhr, error, code) {
console.log(JSON.parse(xhr.responseText.errors));
console.log(xhr);
console.log(error);
new Noty({
type: "error",
layout: "topRight",
text: JSON.parse(xhr.responseText.errors)
}).show();
}
},
columns: [
{ data: "id", title: "User ID" },
{ data: "name", title: "Name" },
{ data: "hometown", title: "Hometown" },
{
data: "employment.started_at",
title: "Date Started",
searchable: false
},
{ data: "status", title: "Status", searchable: false },
{
data: "action",
title: "Action",
orderable: false,
responsivePriority: -1
}
],
initComplete(settings) {
rowCounter.html(`${settings.fnRecordsTotal()} Total`);
}
});
My expected results is that my controller code can me refactored to go inside of the UsersDataTable class.
UPDATE:
I am working on what was provided to me below however, I have since decided to separate the view from its API to get the collection of users for the table to use so I won't need to create the table with the package. The problem is none of the code in the dataTable method is being ran. What am I doing wrong?
So currently as an update, I have the following.
public function index(UsersDataTable $dataTable, UserFilters $requestFilter)
{
$this->authorize('viewList', User::class);
$query = User::query();
$requestFilter->apply($query);
return $dataTable->eloquent($query)->toJson();
}
<?php
namespace App\DataTables;
use App\Models\User;
use App\Filters\UserFilters;
use Yajra\DataTables\DataTables;
class UsersDataTable extends DataTables
{
/** @var userFilters */
private $userFilters;
/**
* UserDataTable constructor.
*
* @param UserFilters $userFilters
*/
public function __construct(UserFilters $userFilters)
{
$this->userFilters = $userFilters;
}
/**
* Build DataTable class.
*
* @param mixed $query Results from query() method.
* @return \Yajra\DataTables\DataTableAbstract
*/
public function dataTable($query)
{
return datatables($query)
->editColumn('started_at', function (User $user) {
return $user->currentEmployment->started_at->format('Y-m-d H:s');
})
->editColumn('name', function (User $user) {
return $user->full_name;
})
->filterColumn('id', function ($query, $keyword) {
$query->where($query->qualifyColumn('id'), $keyword);
})
->filterColumn('name', function ($query, $keyword) {
$sql = "CONCAT(users.first_name, ' ', users.last_name) like ?";
$query->whereRaw($sql, ["%{$keyword}%"]);
})
->addColumn('action', 'users.partials.action-cell');
}
/**
* Get query source of dataTable.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function query($builder)
{
$query = User::with('employment');
$this->userFilters->apply($query);
return $query;
}
}