Individual column filtering using datatable - ajax

My target is to have an individual filtering for column. My reference is: https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html
The problem I am encountering right now when I type, my datatable doesn't do any filtering and it shows an error regarding CURSORPOSITION:
I followed the guide thoroughly and made a lots of research but I still failed to achieve my goal. I hope you can help me
Views:
<table id="example" class="table table-bordered table-hover table-striped is-narrow is-hoverable is-fullwidth text-nowrap" style="width: 100%;">
<thead>
<tr>
<th>TESTING ID</th>
<th>TESTING ACTION</th>
<th>TESTING DESC</th>
<th>TESTING Date</th>
<th>TESTING VENUE</th>
<th>TESTING TICKET</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Ajax:
$(document).ready(function() {
$('#example thead tr')
.clone(true)
.addClass('filters')
.appendTo('#example thead');
table = $('#example').DataTable({
dom: 'lfrtip',
"processing": false, //Feature control the processing indicator.
"serverSide": true, //Feature control DataTables' server-side processing mode.
orderCellsTop: true,
fixedHeader: true,
initComplete: function () {
var api = this.api();
// For each column
api
.columns()
.eq(0)
.each(function (colIdx) {
// Set the header cell to contain the input element
var cell = $('.filters th').eq(
$(api.column(colIdx).header()).index()
);
var title = $(cell).text();
$(cell).html('<input type="text" placeholder="' + title + '" />');
// On every keypress in this input
$(
'input',
$('.filters th').eq($(api.column(colIdx).header()).index())
)
.off('keyup change')
.on('change', function (e) {
// Get the search value
$(this).attr('title', $(this).val());
var regexr = '({search})'; //$(this).parents('th').find('select').val();
var cursorPosition = this.selectionStart;
// Search the column for that value
api
.column(colIdx)
.search(
this.value != ''
? regexr.replace('{search}', '(((' + this.value + ')))')
: '',
this.value != '',
this.value == ''
)
.draw();
})
.on('keyup', function (e) {
e.stopPropagation();
$(this).trigger('change');
$(this)
.focus()[0]
.setSelectionRange(cursorPosition, cursorPosition);
});
});
},
// Load data for the table's content from an Ajax source
"ajax": {
"url": "<?php echo site_url('controller/lists')?>",
"type": "POST",
async:true,
dataType: "json",
"data": function(data){
},
},
//Set column definition initialization properties.
"columnDefs": [
{
"targets": [ 0 ], //first column
"orderable": false, //set not orderable
},
{
"targets": [ -1 ], //last column
"orderable": false, //set not orderable
},
],
});
});

Related

How to get the data for a DataTable from the Controller to View using Ajax

In my main controller, I have a function that gets the data from the database, formats it and output it as JSON. My problem now is how to display this data to the DataTable. Most examples I read have the data saved from a different file from the controller. I would for the data to be from a function in the controller. How do I call that function?
View (SampleView.php)
<table id="example" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th>EmpID</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</thead>
</table>
<script type="text/javascript">
$( document ).ready(function() {
var table = $('#example').DataTable( {
"ajax": "main/getDataFunction",
// "ajax": "getDataFunction",
// "ajax": "<?php echo base_url()."main/getDataFunction"; ?>",
// "ajax": { url: 'main/getDataFunction', type: 'POST' },
"bPaginate":true,
"bProcessing": true,
"pageLength": 10,
"columns": [
{ mData: 'EmpID' } ,
{ mData: 'FirstName' },
{ mData: 'LastName' }
]
});
});
</script>
Controller (Main.php)
function getDataFunction() {
$sampleData = $this->db->getSampleData();
$data = array();
foreach($sampleData as $key) {
array_push($data, array("EmpID" => $key->empID,
"FirstName" => $key->firstName,
"LastName" => $key->lastName));
}
$results = array("sEcho" => 1,
"iTotalRecords" => count($data),
"iTotalDisplayRecords" => count($data),
"aaData"=>$data);
echo json_encode($results);
}
Output of echo json_encode($results)
{"sEcho":1,"iTotalRecords":1,"iTotalDisplayRecords":1,"aaData":[{"EmpID":"1","FirstName":"JOHN","LastName":"DOE"}]}
I am not sure about DataTable but what you can do is you can use eval() to evaluate json data first and then fetch your json response values into view.
Old way which I knew is —
$.ajax(function() {
type : 'get', // or 'post',
data : {key:value},
dataType : 'json',
success : function(response){
var html_data = response.eval(); // this will serialize your data object
$('selector').val(html_data.name);
// $('selector').val(html_data.sEcho); as per your output of the code.
// or
$('selector').html(html_data);
}
});

Datatables - wrap td to content

I have a table in which some of the columns contain very short data.
Example:
I want such columns to be smaller but the columnDefs doesn't work:
<div class="table-responsive">
<table id="my_table" class="table table-hover">
...
</table>
</div>
and here's my jquery:
let table = $('#' + table_id).DataTable({
"scrollX": true,
"order": order,
"columnDefs": [
{"width": "5%", "targets": [9,10,11]}
]
});
I use Bootstrap4.
OK so turns out what caused this was the fact that I also added search to each column using 'input'.
$('#' + table_id + ' tfoot th').each(function () {
const title = $(this).text();
if (title) {
$(this).html('<input type="text" placeholder="search..."/>');
}
});
This made all columns the same width. To fix this I added 'style="width:100%"'.
$('#' + table_id + ' tfoot th').each(function () {
const title = $(this).text();
if (title) {
$(this).html('<input style="width:100%" type="text" placeholder="search..."/>');
}
});

How to SUM cells from DataTables when checked?

I want to SUM values from cells when I check then. Like:
I´ve found how on DataTables website but it is not quite like I need.
Will be a lot of data on this table, and I want to SUM their values when the checkbox is checked, the save the total on a variable to pass to a controller.
P.S.: I forgot to say that I am using VueJS. Let´s see some code.
#section('scripts')
<script type="text/javascript"
src="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.16/af-2.2.2/b-1.5.1/b-colvis-1.5.1/b-flash-1.5.1/b-html5-1.5.1/b-print-1.5.1/cr-1.4.1/fh-3.1.3/kt-2.3.2/rg-1.0.2/rr-1.2.3/sl-1.2.5/datatables.min.js">
</script>
<script type="text/javascript" src="{{ asset('js/moment-with-locales.min.js') }}"></script>
<script>
var vue = new Vue({
el: '#app',
data: {
isLoading: false,
cliente: '{{ $contemplado->id }}',
checked : false,
nrocpfCnpj: "{!! $contemplado->cpfCnpj !!}",
porte: '{!! $contemplado->porte !!}',
natureza_juridica: '{!! $contemplado->natureza_juridica !!}',
idERP: '{!! $contrato->idERP !!}',
originalSegmento: '{!! $contrato->originalSegmento !!}',
novoSegmento: '{!! $contrato->novoSegmento !!}',
isLoading: false,
grupo: '{!! $contrato->grupo !!}',
cota: '{!! $contrato->cota !!}',
},
mounted() {
const vm = this
var tabela = $('#example').dataTable({
"language": {
'url': '//cdn.datatables.net/plug-ins/1.10.16/i18n/Portuguese-Brasil.json'
},
'scrollX': true,
'scrollY': false,
'autoWidth': true,
responsive: true,
processing: true,
"ajax": {
"url": "montaTabelaMultiCota",
"data": {
"nrocpfCnpj": vm.nrocpfCnpj
}
},
columns: [
{ data: null,
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("<div class='form-check'><input class='form-check-input' type='checkbox' name='cota"+oData['NUMERO-COTA']+"' value='"+oData['VALOR-BEM']+"'></div>")
}
},
{ data: 'CODIGO-GRUPO'},
{ data: 'NUMERO-COTA',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
$(nTd).html(oData['NUMERO-COTA'])
}
},
{ data: 'DESCRICAO-BEM'},
{ data: 'VALOR-BEM',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("R$ "+oData['VALOR-BEM']+",00")
}
},
{ data: 'NUMERO-CONTRATO'},
{ data: 'DATA-CONTEMPLACAO',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
moment.locale('pt-br');
var data = oData['DATA-CONTEMPLACAO'];
let criado = moment(data, 'YYYYMMDD').fromNow();
$(nTd).html(criado);
}
},
{ data: 'DATA-ENTREGA',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
moment.locale('pt-br');
var data = oData['DATA-ENTREGA'];
let criado = moment(data, 'YYYYMMDD').fromNow();
$(nTd).html(criado);
}
}
]
});
// Adds the values and updates the readonly input.
function updateTotal(){
$('input#total').val($('input.selected:checked').toArray().reduce(function(last, current){
return last + parseInt($(current).attr('data-value'));
}, 0));
}
// init the total value and bind updateTotal function to the change event on the checkboxes.
function dt_init(){
updateTotal();
$('.selected').off('change').on('change', function(e) {
updateTotal();
});
}
var dt = $('#dt_container').DataTable({
// Add the checkboxes and set the values in a data-* attribute for later
rowCallback: function(row, data){
let value = parseInt($('td:eq(4)', row).html().substring(3))
// $('td:eq(4)', row).html() : 'R$ 12975.00'
// 'R$ 12975.00'.substring(3) : '12975.00'
// parseInt('12975.00') : 12975
$('td:eq(0)', row).html(`<input class="selected" type="checkbox" data-value=${value}>`)
},
// If you need to redraw your table (sort, search, page), then you need to redo some things, that's why dt_init is called upon every time.
initComplete: function(settings, json, param){
// show the footer after the DataTable is done
$(dt.table().footer()).css('display', '');
dt_init();
},
drawCallback: function(settings){
dt_init();
}
});
},
});
</script>
#endsection
Any helps?
Thanks a lot!
You can use a footer in your datatable. Just make it initially invisible and add some boilerplate to show some results.
<table id="dt_container">
<tfoot style="display: none;">
<tr>
<th>Total:</th>
<th><input id="total" type="text" name="total" value="" readonly></th>
</tr>
</tfoot>
</table>
Next, in the javascript init the DataTable but add some callbacks
// Adds the values and updates the readonly input.
function updateTotal(){
$('input#total').val($('input.selected:checked').toArray().reduce(function(last, current){
return last + parseInt($(current).attr('data-value'));
}, 0);
}
// init the total value and bind updateTotal function to the change event on the checkboxes.
function dt_init(){
updateTotal();
$('.selected').off('change').on('change', function(e){
updateTotal();
});
}
var dt = $('#dt_container').DataTable({
// Add the checkboxes and set the values in a data-* attribute for later
rowCallback: function(row, data){
let value = parseInt($('td:eq(4)', row).html().substring(3))
// $('td:eq(4)', row).html() : 'R$ 12975.00'
// 'R$ 12975.00'.substring(3) : '12975.00'
// parseInt('12975.00') : 12975
$('td:eq(0)', row).html(`<input class="selected" type="checkbox" data-value=${value}>`)
},
// If you need to redraw your table (sort, search, page), then you need to redo some things, that's why dt_init is called upon every time.
initComplete: function(settings, json, param){
// show the footer after the DataTable is done
$(dt.table().footer()).css('display', '');
dt_init();
},
drawCallback: function(settings){
dt_init();
}
});

Laravel Yajra DataTable - Fetch content via Ajax with supplied search parameters

After searching as to how to fill up a Yajra DataTable with data from an ajax call with user supplied search parameters, I came to this page for the official documentation.
It has a code snippet as follows...
$builder->ajax([
'url' => route('users.index'),
'type' => 'GET',
'data' => 'function(d) { d.key = "value"; }',
])
However, I cannot make anything out of it. Where does the $builder variable come from? How do I use the data received from the Ajax call to fill up the table? This page lists the callback functions with no details.
What I need
A full-blown example of how to fill up my data table with data received from an Ajax call initiated by the search button #btn_search after selecting a value from the drop-down #param.
For simplicity, lets assume that the table structure looks like...
<select id="param">
<option value="">Select </option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
<button id="btn_search" value="Search">Search</button>
<table>
<thead>
<tr>
<th>Serial</th>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
</table>
The controller method that returns the data...
<?php
public function getBasicData()
{
$users = User::select(['id','name','email','address']);
return Datatables::of($users)->make();
}
The user selects a value from the dropdown and clicks on the search button. In the actual scenario, several dropdowns are there to collect the search parameters. Relevant jQuery code is...
$("#btn_search").click(function() {
var param_value = $("#param").val().trim();
// make ajax call probably
});
How can I make the Ajax call inside the click handler and fill up the data table with the received data?
The $builder variable is the class id of the table that would view the information ,
Here is an example :
<table id="data" class="table table-bordered table-hover" >
<thead>
<tr class="table-head">
<th>#</th>
<th>namr</th>
<th>email</th>
<th>date</th>
<th>auth</th>
<th>control</th>
<th>control</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<th> </th>
<th> </th>
<th> </th>
<th> </th>
<th></th>
<th></th>
<th></th>
</tfoot>
</table>
and this is ajax code
<script type="text/javascript">
var lastIdx = null;
var table = $('#data').DataTable({
processing: true,
serverSide: true,
ajax: '{{ url('/adminpanel/users/data') }}',
columns: [
{data: 'id', name: 'id'},
{data: 'name', name: 'name'},
{data: 'email', name: 'email'},
{data: 'created_at', name: 'created_at'},
{data: 'admin', name: 'isadmin'},
{data: 'edit', name: 'edit', orderable: false, searchable: false},
{data: 'action', name: 'action', orderable: false, searchable: false}
],
"language": {
"url": "{{ Request::root() }} /admin/cus/Arabic.json"
},
"stateSave": false,
"responsive": true,
"order": [[0, 'asc']],
"pagingType": "full_numbers",
aLengthMenu: [
[25, 50, 100, 200, -1],
[25, 50, 100, 200, "All"]
],
iDisplayLength: 25,
fixedHeader: true,
"oTableTools": {
"aButtons": [{
"sExtends": "csv",
"sButtonText": "ملف إكسل",
"sCharSet": "utf16le"
},
{
"sExtends": "copy",
"sButtonText": "نسخ المعلومات",
},
{
"sExtends": "print",
"sButtonText": "طباعة",
"mColumns": "visible",
}
],
"sSwfPath": "{{ Request::root() }} /website/admin/cus/copy_csv_xls_pdf.swf"
},
"dom": '<"pull-left text-left" T><"pullright" i><"clearfix"><"pull-right text-right col-lg-6" f > <"pull-left text-left" l><"clearfix">rt<"pull-right text-right col-lg-6" pi > <"pull-left text-left" l><"clearfix"> '
,initComplete: function ()
{
var r = $('#data tfoot tr');
r.find('th').each(function(){
$(this).css('padding', 8);
});
$('#data thead').append(r);
$('#search_0').css('text-align', 'center');
}
});
table.columns().eq(0).each(function(colIdx) {
$('input', table.column(colIdx).header()).on('keyup change', function() {
table
.column(colIdx)
.search(this.value)
.draw();
});
});
table.columns().eq(0).each(function(colIdx) {
$('select', table.column(colIdx).header()).on('change', function() {
table
.column(colIdx)
.search(this.value)
.draw();
});
$('select', table.column(colIdx).header()).on('click', function(e) {
e.stopPropagation();
});
});
$('#data tbody')
.on( 'mouseover', 'td', function () {
var colIdx = table.cell(this).index().column;
if ( colIdx !== lastIdx ) {
$( table.cells().nodes() ).removeClass( 'highlight' );
$( table.column( colIdx ).nodes() ).addClass( 'highlight' );
}
} )
.on( 'mouseleave', function () {
$( table.cells().nodes() ).removeClass( 'highlight' );
} );
</script>
this is a full table with ajax example ,like Yajara documentation help .

ajax is not accessing to my button inside datatable

I want to access to my button inside datatable which is inside of my modal, but when I want to access it wont load any alert , ajax url or whatever thing even If I change id or class of "a" tag. how can I fix it? this ajax I know it wont load and error in console, but it also show it..
ajax
$(function(event) {
URL_GET_VIEW_SEARCH_PRODUCT = BASE_URL + 'sale/sales/getViewSearch';
URL_GET_DATATABLE = BASE_URL + 'sale/sales/datatable';
URL_SEARCH_PRODUCT = BASE_URL + 'sale/sales/search_product';
$('#btn-search').click(function (e) {
BootstrapDialog.show({
title: 'Search Product',
message: function(dialog) {
var $message = $('<div></div>');
var pageToLoad = dialog.getData('pageToLoad');
$message.load(pageToLoad);
return $message;
},
data: {
pageToLoad: URL_GET_VIEW_SEARCH_PRODUCT
},
onshown: function(dialog){
$('#example').DataTable({
lengthChange: false,
responsive: true,
ajax: {
url: URL_GET_DATATABLE,
type: 'POST',
},
columnDefs: [{
targets: 4,
data: null,
defaultContent: "<a href='#'><span class='glyphicon glyphicon-plus'></span></a>"
}],
});
}
});
});
$('#search').typeahead({
source: function (query,process) {
$.ajax({
url: URL_SEARCH_PRODUCT,
type: 'POST',
data: {query: query},
dataType: 'json',
async: true,
success: function (data) {
console.log(data);
process(data);
}
});
}
});
$('#example tbody').on('click', 'a', function(event) {
$.ajax({
url: '/path/to/file',
type: 'default GET (Other values: POST)',
dataType: 'default: Intelligent Guess (Other values: xml, json, script, or html)',
data: {param1: 'value1'},
})
});
});
table view
<table id="example" class="table table-bordered table-striped" cellspacing="0" width="100%">
<thead>
<tr>
<th>Code</th>
<th>Description</th>
<th>Stock</th>
<th>Price</th>
<th></th>
</tr>
</thead>
</table>

Resources