Can somebody explain me with a simple example how to implement custom filter in Datatable as a service Implementation. I couldn't understand a thing from tutorials.
Let me try if I can explain it for you.
On your DT Service class you have an ajax()
method that handles the ajax json response to client-side. This is the place where you transform your json response by editing/adding column, etc...
Another method is the query()
method that handles your base query to be use by DT. The class has request()
method that you can use to access the Request
instance. See example snippet below:
public function ajax()
{
return $this->datatables
->eloquent($this->query())
->addColumn('action', 'audits.audit.datatables.action')
->make(true);
}
public function query()
{
$audits = Audit::query();
if ($this->request()->get('auditType')) {
$audits->where('type', $this->request()->get('auditType'));
}
return $this->applyScopes($audits);
}
Hope this helps. Will try to add more demo on service implementation soon.
Thanks. I got this part. Can you tell me how to send ajax data from client and then redraw the table ?
Hook your js on preXHR
event of DT to pass custom data to server. https://datatables.net/reference/event/preXhr
Now custom filter works but pagination is not working with it.
Thanks, I solved it.
Hi Can I see an example???
See the above code snippet by @yajra. Or if you are looking for JavaScript snippet tell me.
in the above Request example with 'auditType' -- where is this posted from? the blade? can it be posted from a controller?
From the Javascript, here is the example code :
$('#dataTableBuilder')
.on('preXhr.dt', function ( e, settings, data ) {
data.auditType= $('input[name=auditType').val();
});
<input type="text" onchange="abc(this.value)" >
function abc(a) {
$('.datatable')
.on('preXhr.dt', function ( e, settings, data ) {
data.auditType = a;
});
}
sir, iam using datatable service too, why i cannot loaddata after onchange ..
Hi i do as follows: i catch the change event and click the reload button on datatable, like this:
$(selector).on('change',function(){
$('.buttons-reload').click();
});
Im not pretty sure its the right way to update the table, but it works.
Hi, could you please help me? Who makes the request in this case.
My view:
<input type="text" name="abc">
<div class="col-md-12">
{!! $dataTable->table(['style'=>'width:100%', 'class'=>'table table-striped table-hover']) !!}
</div>
ClientsDataTable:
`
public function query()
{
$workstation_id = Auth::user()->activeWorkstation()->id;
$clients = Client::where('workstation_id', $workstation_id)->with('addresses')->with('devices');
if ($this->request()->get('abc')) {
$clients->where('name', $this->request()->get('abc'));
}
return $this->applyScopes($clients);
}
JS:
$('#dataTableBuilder').on('preXhr.dt', function ( e, settings, data ) {
data.abc= $('input[name=abc]').val();
});
`
Please help, I don't know who supposed to send the request.
The datatable makes the request every time you change the values on your custom filter.
You need to catch the change,keyup or keydown event on the input, like:
$(selector).on('change',function(){
$('.buttons-reload').click();
});
The buttons-reload is a button that you configure on the datatable class:
public function html()
{
return $this->builder()
->columns($this->getColumns())
->addAction(['width' => '35%'])
->parameters([
'language' => [
'url' => '//cdn.datatables.net/plug-ins/1.10.11/i18n/Spanish.json'
],
"lengthMenu" => [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
"pagingType" => "full_numbers",
'dom' => 'lBfrtip',
'scrollX' => true,
**'buttons' => [
'reload'
],**
]);
}
So when you press keys on the input, and catch the event, the datatable's reload button is clicked, then it provokes the request, the datatable class catch the input value and applies to the query you need to execute.
It works for me, but possibly is a better way to make it works.
Hi,
It did reload the query, but without passed data. Any suggestion?
It works!!! Sorry, i forgot to add on preXhr.dt on the 'on change' event like this:
$('input[name=abc]').on('change',function(){
$('#dataTableBuilder').on('preXhr.dt', function ( e, settings, data ) {
data.abc= $('input[name=abc]').val();
});
$('.buttons-reload').click();
});
I'll just leave this here for anyone who is interested ;)
$(document).ready(function () {
$('.js-datatable-filter-form :input').on('change', function (e) {
window.LaravelDataTables["dataTableBuilder"].draw();
});
$('#dataTableBuilder').on('preXhr.dt', function ( e, settings, data ) {
$('.js-datatable-filter-form :input').each(function () {
data[$(this).prop('name')] = $(this).val();
});
});
});
The extra filter data can be retrieved via the request()
function. Using a scope the results can be filtered in the back-end.
<?php namespace App\DataTables\Scopes;
use Yajra\Datatables\Contracts\DataTableScopeContract;
class ArchivedScope implements DataTableScopeContract
{
public function apply($query)
{
$query->onlyTrashed();
return $query;
}
}
Example controller method:
public function archived(UserDataTable $dataTable)
{
$dataTable->addScope(new App\DataTables\Scopes\ArchivedScope());
return $dataTable->render('admin.users.index');
}
Note the request()
function in the apply
method here.
<?php namespace App\DataTables\Scopes;
use Yajra\Datatables\Contracts\DataTableScopeContract;
class RoleScope implements DataTableScopeContract
{
public function apply($query)
{
if ($roleId = request('role_id')) {
$query->where('role_id', $roleId);
}
return $query;
}
}
More information on the scopes can be found here: https://datatables.yajrabox.com/services/scope
Most helpful comment
I'll just leave this here for anyone who is interested ;)
Javascript
The extra filter data can be retrieved via the
request()
function. Using a scope the results can be filtered in the back-end.Example scopes:
Archived scope
Example controller method:
Role scope
Note the
request()
function in theapply
method here.More information on the scopes can be found here: https://datatables.yajrabox.com/services/scope