Call function after DataTable is filtered - javascript

I have DataTable filled with js-switches, here's the code:
$('#bandsTable').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
'type': 'GET',
'url': 'myUrl',
'data': function (d) {
d._token = Laravel.csrfToken;
}
},
columns: [
{
title: "Number",
data: "number"
},
{
title: "Privileged",
data: "privileged"
}
],
columnDefs: [
{
render: function (data) {
var checked = data ? 'checked' : '';
return '' +
'<input type="checkbox" class="js-switch" id="schedule_deactivation" ' +
checked + ' data-switchery="false" style="display: none;"> \n';
},
targets: 1
}
],
order: [[0, 'asc']],
fnRowCallback: function( nRow, aData, iDisplayIndex ) {
nRow.className = "band-row";
nRow.setAttribute("data-band", aData.number);
return nRow;
},
responsive: true
});
When I filter result's they're displayed correctly, but I don't see checkboxes generated, I can type JS from the console and it works when I type:
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function (html) {
var switchery = new Switchery(html, {
color: '#26B99A',
secondaryColor: '#ff7a77'
});
});
but I don't know when I should call this code. I have no idea about DataTable lifecycle and where should I inject the code. Should it be some callback defined by DataTables or something else?

please see the documentation on the below link for more, but the code should work as follows:
$('#bandsTable').on('draw.dt', function () {
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function (html) {
var switchery = new Switchery(html, {
color: '#26B99A',
secondaryColor: '#ff7a77'
});
});
});
Link:
https://datatables.net/reference/event/

Related

Set default value before click event triggers

I have button groups. Once user clicks on the link, it filters value based on the content in the link. By default I added selected class. I want default value of link which contains selected class to be considered for filtering before click event triggers. It works fine when user clicks on c-btn-group but not considers default value when page loads. As of now it shows complete data without filtering when page loads.
<div class="c-btn-group">
<a class="c-btn selected">Large Cap</a>
<a class="c-btn">Small Cap</a>
<a class="c-btn">virginica</a>
</div>
JS
$('.c-btn-group').on('click', 'a', function(event) {
var searchTerm = this.textContent;
/* 4th column filtering */
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
if (data[3] == searchTerm) {return true;}
return false;
})
table.draw();
$.fn.dataTable.ext.search.pop();
// Add or remove 'selected' class;
event.preventDefault();
$('a').removeClass('selected');
$(this).addClass('selected');
});
Try the below script. Here is demo
Separate out logic of dataTable filtering inside filter function. Get selected text by $('.c-btn-group .selected').text(); and call filter(initialSelectedText);
var myList2;
$.ajax({
url: "https://raw.githubusercontent.com/markwsac/jsonfile/main/jsondata.json",
type: "get",
dataType: 'text',
async: false,
success: function(response) {
if (!response) return;
response = response.slice(0, -1); // trim ";" at the end
window.myList2 = JSON.parse(response);
},
error: function(err) {
console.log(err);
}
});
var myList = window.myList2;
$(document).ready(function () {
table = $("#mfTable").DataTable({
data: myList,
paging: true,
lengthChange: false,
searching: true,
info: false,
columns: [
{ data: 'Fund Name' },
{ data: 'Morningstar Rating' },
{ data: 'Category Rank' },
{ data: 'Category' },
{ data: 'Expense Ratio' },
{ data: 'AUM (Cr)' },
{ data: 'NAV' },
],
columnDefs: [{
"defaultContent": "-",
"targets": "_all"
}]
});
const initialSelectedText = $('.c-btn-group .selected').text();
filter(initialSelectedText);
$('.c-btn-group').on('click', 'a', function(event) {
var searchTerm = this.textContent;
/* 4th column filtering */
filter(searchTerm);
// Add or remove 'selected' class;
event.preventDefault();
$('a').removeClass('selected');
$(this).addClass('selected');
});
});
function filter(searchTerm){
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
if (data[3] == searchTerm) {return true;}
return false;
});
table.draw();
$.fn.dataTable.ext.search.pop();
}
DataTable provides an Option for this. When you are initializing your table, just use the searchCols option which would load the table with the initial search provided. for Example:
table = $("#mfTable").DataTable({
data: myList,
paging: true,
lengthChange: false,
searching: true,
info: false,
columns: [
{ data: 'Fund Name' },
{ data: 'Morningstar Rating' },
{ data: 'Category Rank' },
{ data: 'Category' },
{ data: 'Expense Ratio' },
{ data: 'AUM (Cr)' },
{ data: 'NAV' },
],
columnDefs: [{
"defaultContent": "-",
"targets": "_all"
}],
searchCols: [
null,
null,
null,
{ "search": "Large Cap" },
null,
null,
null,
]
})
Here is the link for this option https://datatables.net/reference/option/searchCols
You can also use the libraries own search method rather than implementing it yourself, so instead of writing:
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
if (data[3] == searchTerm) {return true;}
return false;
})
table.draw();
$.fn.dataTable.ext.search.pop();
just write:
table.column(3).search(searchTerm).draw();

Limit checked , checkbox in bootstrap dataTable

I have this code below to click a checkbox in my DataTable and get the IDs and store in an array. For Example I have a 2 seperate DataTables First is for President and second is for the Senators.
We know that we can only vote 1 in President and for Senators we can choose many.
My problem here is I can check how many checkboxes in the DataTables. How to limit the checked checkboxes?.
Still learning in bootstrap here.
JS Code
var dataTablestest = $("#tbltest").DataTable({
responsive: true,
processing: true,
info: true,
search: true,
stateSave: true,
order: [[1, "asc"], [2, "asc"]],
lengthMenu: [[50, 100, 200, -1], [50, 100, 200, "All"]],
ajax: { "url": "/Voting/LoadTableTest" },
columns:
[
{ data: "testID", title: "", visible: false, searchable: false },
{ data: "Fullname", title: "FullName", sClass: "alignRight" },
{ data: "Position", title: "Position", sClass: "alignRight" },
{ data: "party", title: "Party", sClass: "alignRight" },
{ data: "ActionMenu", title: "Click to vote", searchable: false, orderable: false, sClass: "alignCenter",
"mRender": function (data) {
return '<center><label><input class="checkId" type="checkbox" id="chkvote_' + data + '" value=""/></label></center>';
}
}
]
});
var arrayIds = [];
$('#tbltest tbody').on('click', 'tr', function (e) {
if ($(e.target).is(".checkId")) {
var Ids = dataTablestest.row(this).data().testID;
arrayIds.push(Ids);
return
}
});
EDIT
I found an answer but there is a problem with it. My counter keeps increment every time I check a checkbox from my dataTable.
$('#tbltest tbody').on('click', 'tr', function (e) {
if ($(e.target).is(".checkId")) {
if ($(e.target).is(":checked") == true) {
CheckCount = CheckCount + 1;
var Ids = dataTablestest.row(this).data().testID;
if (CheckCount > 1) {
return false;
}
arrayIds.push(Ids);
return
}
else {
CheckCount = parseInt(CheckCount) - parseInt(1);
}
}
});
I use this code below.. Thanks to all who view my thread.
var arrayIds = [];
$('#tbltest tbody').on('click', 'tr', function (e) {
if ($(e.target).is(".checkId")) {
var Ids = dataTablestest.row(this).data().testID;
if ($(e.target).is(":checked") == true) {
var lenArray = arrayIds.length;
if (lenArray < 1) {
arrayIds.push(Ids);
} else {
return false;
}
}
else {
for (var i = arrayIds.length - 1; i >= 0; i--) {
if (arrayIds[i] === Ids) {
arrayIds.splice(i, 1);
}
}
}
}
return;
});

jquery datatable - applying value for select.className is not working as expected

I am trying to change the background color of selected row(s) in jquery datatable using my own css class but, the tick mark in the checkbox is not appearing.
If I remove className: 'selected-row' from the below code, then everything works normal but, without the color I want.
Fiddler: https://jsfiddle.net/8f63kmeo/12/
HTML:
<table id="CustomFilterOnTop" class="table table-bordered table-condensed" width="100%"></table>
JS
var Report4Component = (function () {
function Report4Component() {
//contorls
this.customFilterOnTopControl = "CustomFilterOnTop"; //table id
//data table object
this.customFilterOnTopGrid = null;
//variables
this.result = null;
}
Report4Component.prototype.ShowGrid = function () {
var instance = this;
//create the datatable object
instance.customFilterOnTopGrid = $('#' + instance.customFilterOnTopControl).DataTable({
columns: [
{ title: "<input name='SelectOrDeselect' value='1' id='ChkBoxSelectAllOrDeselect' type='checkbox'/>" },
{ data: "Description", title: "Desc" },
{ data: "Status", title: "Status" },
{ data: "Count", title: "Count" }
],
"paging": true,
scrollCollapse: true,
"scrollX": true,
scrollY: "300px",
deferRender: true,
scroller: true,
dom: '<"top"Bf<"clear">>rt <"bottom"<"Notes">i<"clear">>',
buttons: [
{
text: 'Load All',
action: function (e, dt, node, config) {
instance.ShowData(10000);
}
}
],
columnDefs: [{
orderable: false,
className: 'select-checkbox text-center',
targets: 0,
render: function (data, type, row) {
return '';
}
}],
select: {
style: 'multi',
selector: 'td:first-child',
className: 'selected-row'
}
});
};
Report4Component.prototype.ShowData = function (limit) {
if (limit === void 0) { limit = 100; }
var instance = this;
instance.customFilterOnTopGrid.clear(); //latest api function
instance.result = instance.GetData(limit);
instance.customFilterOnTopGrid.rows.add(instance.result.RecordList);
instance.customFilterOnTopGrid.draw();
};
Report4Component.prototype.GetData = function (limit) {
//structure of the response from controller method
var resultObj = {};
resultObj.Total = 0;
resultObj.RecordList = [];
for (var i = 1; i <= limit; i++) {
resultObj.Total += i;
var record = {};
record.Description = "This is a test description of record " + i;
record.Status = ["A", "B", "C", "D"][Math.floor(Math.random() * 4)] + 'name text ' + i;
record.Count = i;
resultObj.RecordList.push(record);
}
return resultObj;
};
return Report4Component;
}());
$(function () {
var report4Component = new Report4Component();
report4Component.ShowGrid();
report4Component.ShowData();
});
function StopPropagation(evt) {
if (evt.stopPropagation !== undefined) {
evt.stopPropagation();
}
else {
evt.cancelBubble = true;
}
}
Issue:
Any suggestion / help will be greatly appreciated.
It's the class selected that sets the checkbox tick etc. and by using a different class the selected class is no longer added.
You can just add both those classes instead, and it should work
select: {
style: 'multi',
selector: 'td:first-child',
className: 'selected-row selected'
}
FIDDLE

Tabbing doesnt work for datatable

I m using jquery datatables in many pages and its working good in every page and in a single page its not working properly, i mean when i use tab to go through datatable, it works fine for the first time and when i try to do the same for second time, if i try to focus on any thing in few seconds in data table, the focus disappears and the foucs starts from the starting of the page.
Here goes the code
function tableCall(){
var clientId = $('#clientId').val();
var versionCount = $('#versionCount').val();
var fromDate = $('#fromDate').val();
var toDate = $('#toDate').val();
$.ajax({
url: auditTrail.props.reporttableURL,
type: "POST",
dataType: "json",
data: {
clientId:clientId,
versionCount:versionCount,
fromDate:fromDate,
toDate:toDate
},
success: function (data) {
searchJSON = data.data;
var len=searchJSON.length;
if (len > 0){
$('.no-data, #warning-sign').hide();
createTable();
}else{
$('.no-data').hide();
$('#warning-sign').show();
}
}
});
}
function createTable() {
wwhs.setADAAttrDynamic($('#auditTable'));
if ($.fn.DataTable.isDataTable('#auditTable')) {
// table.destroy();
$("#auditTable tbody").empty();
}
table = $('#auditTable').dataTable({
"searching":false,
"destroy":true,
"autoWidth": false,
"ordering": true,
"destroy":true,
"stateSave": true,
"drawCallback": attachEvents,
"stateLoadParams": function (settings, data) {
return false;
},
data: searchJSON,
columns: [{
data: "reportName"
}, {
data: "reportStatus"
}, {
data: "timeStamp"
}, {
data: "requestedBy"
}],
"columnDefs": [{
"render": function (data, type, row) {
if(row.reportStatus.toUpperCase() == 'PROCESSED')
return '<a class="blue-text" " data-name="'+ row.reportName +'">' + row.reportName + '</a>';
else
return row.reportName;
},
"width": "50%",
"targets": 0
}, {
"width": "15%",
"targets": 1
}, {
"width": "20%",
"targets": 2
}, {
"width": "15%",
"targets": 3
}]
});
}
I think the problem is because the datatable instance is not destroyed.
Since datatables saves all the nodes into an object and renders it when ever it wants, emptying the tbody doesnt do anything. it just removes the elements in the page which can be re-drawn/re-rendered by datatable from its stored object.
You can check if the object is already initialized and the destroy it before re-initializing.
if(typeof table != "undefined")
table.destroy();
So the final code will look something like
function tableCall(){
var clientId = $('#clientId').val();
var versionCount = $('#versionCount').val();
var fromDate = $('#fromDate').val();
var toDate = $('#toDate').val();
$.ajax({
url: auditTrail.props.reporttableURL,
type: "POST",
dataType: "json",
data: {
clientId:clientId,
versionCount:versionCount,
fromDate:fromDate,
toDate:toDate
},
success: function (data) {
searchJSON = data.data;
var len=searchJSON.length;
if (len > 0){
$('.no-data, #warning-sign').hide();
createTable();
} else {
$('.no-data').hide();
$('#warning-sign').show();
}
}
});
}
function createTable() {
wwhs.setADAAttrDynamic($('#auditTable'));
if ($.fn.DataTable.isDataTable('#auditTable')) {
if(typeof table != "undefined")
table.destroy();
}
table = $('#auditTable').dataTable({
"searching":false,
"destroy":true,
"autoWidth": false,
"ordering": true,
"destroy":true,
"stateSave": true,
"drawCallback": attachEvents,
"stateLoadParams": function (settings, data) {
return false;
},
data: searchJSON,
columns: [{
data: "reportName"
}, {
data: "reportStatus"
}, {
data: "timeStamp"
}, {
data: "requestedBy"
}],
"columnDefs": [{
"render": function (data, type, row) {
if(row.reportStatus.toUpperCase() == 'PROCESSED')
return '<a class="blue-text" " data-name="'+ row.reportName +'">' + row.reportName + '</a>';
else
return row.reportName;
},
"width": "50%",
"targets": 0
}, {
"width": "15%",
"targets": 1
}, {
"width": "20%",
"targets": 2
}, {
"width": "15%",
"targets": 3
}]
});
}

Refresh / Redraw Datatables over function

and i call the datatable over the function.
Here is my function :
function drawTable(yearParameter) {
var oTable = $('#horizontal-monthly').DataTable({
processing: true,
serverSide: true,
ajax: {
url : '{!! route('adm1n.laporan-bulanan-data') !!}',
data : function (d) {
d.year = yearParameter;
}
},
columns: [
{ data: 'B_01', name: 'B_01', sortable: false },
{ data: 'B_02', name: 'B_02', sortable: false }
],
dom : '<"dt-panelmenu clearfix"lr>t<"dt-panelfooter clearfix"ip>',
});
}
And i have event change to call my function above and pass parameter on it.
How to reload the datatables? Cause right now datatables won't reload.
I try to use :
oTable.destroy();
oTable.draw();
It make datatables functionality not work. Like search, pagination etc.
Edit
Here is my change event :
$('#year-value').on('change', function(e) {
var yearParam = $('#year-value').val();
drawTable(yearParam);
});
How to handle that?
Thank you??
Please try
oTable.clear();
oTable.draw();
Also, can I see your change event? I can help you re-add the rows
UPDATE 2
Ok, you can't call DT constructor more than once. First thing what you want to do is to save DT object as global object.
function drawTable() {
if(!oTable)
{
oTable = $('#horizontal-monthly').DataTable({
processing: true,
serverSide: true,
ajax: {
url : '{!! route('adm1n.laporan-bulanan-data') !!}',
data : function (d) {
d.year = filterYearParam;
}
},
columns: [
{ data: 'B_01', name: 'B_01', sortable: false },
{ data: 'B_02', name: 'B_02', sortable: false }
],
dom : '<"dt-panelmenu clearfix"lr>t<"dt-panelfooter clearfix"ip>',
});
}
}
else
{
oTable.ajax.reload().draw();
}
$('#year-value').on('change', function(e) {
filterYearParam = $('#year-value').val();
drawTable();
});
Try this, and then I can try making your year to work.

Categories

Resources