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();
Related
I have a jquery autocomplete that once a value is selected it loads a datatable with checkbox from an ajax call. Then while submitting the form I need to access the datatable variable to iterate each row to get the selected ones, but the datatable variable appears as undefined.
I'm doing the same as in this example, only difference is the data is coming from an Ajax request.
Can you please help me understand why is that happening?
$(document).ready(function() {
var campId;
var t_OmnitureCode;
// Campaign input autocomplete
$("#campaign").autocomplete({
source: function(request, response) {
$.ajax({
url: "promotion",
type: "GET",
data: {
term: request.term,
action: "searchCampaign"
},
dataType: "json",
success: function(data) {
if (!data.length) {
var result = [{
label: "no match found",
value: "-1"
}];
response(result);
} else {
response($.map(data, function(item) {
return {
label: item.name,
value: item.campaignId
}
}));
}
}
});
},
select: function(event, ui) {
event.preventDefault();
campId = ui.item.value;
if (campId != "-1") {
this.value = ui.item.label;
// This will apply datatables getting the content from an Ajax call
t_OmnitureCode = applyDataTableOmnitureCode(campId);
}
},
focus: function(event, ui) {
event.preventDefault();
this.value = ui.item.label;
}
});
// Handling form submission
$("#frm_promotion").on("submit", function(e) {
var form = this;
// Variable for datatable "t_OmnitureCode" is undefined below
var rows_selected = t_OmnitureCode.column(0).checkboxes.selected();
EDIT:
Just realized that even while assigning the variable (t_OmnitureCode = applyDataTableOmnitureCode(campId);) it is undefined, not sure why.
Here is the applyDataTableOmnitureCode code:
function applyDataTableOmnitureCode(campId) {
$("#tbl_omnitureCode").DataTable({
destroy: true,
scrollX: true,
fixedColumns: {
leftColumns: 1
},
"ajax": {
"url": "promotion",
"type": "GET",
"data": {
action: "searchOmnitureCodesByCampaignId",
campaignId: campId
},
"dataSrc": ""
},
"columns": [
{ "data": "key" },
{ "data": "omnitureCode" },
{ "data": "urlAppName" },
{ "data": "language" },
{ "data": "channel" },
{ "data": "createDateTime", "defaultContent": "" },
{ "data": "updateDateTime", "defaultContent": "" }
],
"columnDefs": [
{ "targets": 0, "checkboxes": { "selectRow": true } }
],
"select": {
"style": "multi"
},
"order": [[1, "asc"]],
"fnInitComplete": function() {
$("#omnitureCodeSection").show();
}
});
};
You may need to grab your DataTables object into a variable before using that:
var t_OmnitureCode = $("#tbl_omnitureCode").DataTable();
var rows_selected = t_OmnitureCode.column(0).checkboxes.selected();
And, by the way, your method of populating DataTable with external ajax-call is suboptimal. There's an ajax option for that purpose where you can specify all the necessary parameters and get better integration with DataTables API and better performance (as you don't really need to destroy and create your DataTable upon each refresh).
You would simply need to trigger .ajax.reload() whenever you need to refresh your table data.
It's a matter of scope : You declare the variable table inside $(document).ready function.
You may want to put it outside in the global scope :
var table;
$(document).ready(function() {
table = $('#example').DataTable({
...
});
How could I perform If else like method in datatable? The variable 'data' returns the value of the variable, which is correct, but if it is blank, it would return the word "from1", "from2" which is supposed to be the value of the variable "from1". Am I doing the right approach or do you have any suggestion as workaround in this problem? thank you for your answers. here is my code:
var table = $('#records').DataTable({
type: 'post',
"ajax": "getHumanTrainings",
"bPaginate": true,
"bProcessing": true,
"pageLength": 10,
"columns": [{
mData: 'tdesc'
}, {
data: "fdDateFrom2",
defaultContent: 'from1'
}, {
data: "fdDateTo2",
defaultContent: 'from2'
}, {
data: "fcTrainor2",
defaultContent: 'train1'
}, {
mData: 'dur'
}]
});
I'd use the render option for the column data that you have, its much more flexible in terms of wanting something to be displayed by default.
var table = $('#records').DataTable({
type: 'post',
"ajax": "getHumanTrainings",
"bPaginate": true,
"bProcessing": true,
"pageLength": 10,
"columns": [{
mData: 'tdesc'
}, {
data: "fdDateFrom2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for from1>]; // Just use the index for from1
}
// If not blank display data normally
return data;
}
}, {
data: "fdDateTo2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for from2>]; // Just use the index for from2
}
// If not blank display data normally
return data;
}
}, {
data: "fcTrainor2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for train1>]; // Just use the index for train1
}
// If not blank display data normally
return data;
}
}, {
mData: 'dur'
}]
});
I've left comments to give you a guide since I'm not familiar with your data, I would suggest printing out your row first over at render so you'd know which index to use.
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/
I am trying to implement toolbar filtering using jqgrid v4.6 but I'm not able to filter the results
$('form[name="viewComplaintsForm"] button').click(function(e){
e.preventDefault();
var viewForm=$(this).parent('form');
complaintDeptId=viewForm.find('select option:selected').val();
complaintDeptName=viewForm.find('select option:selected').text();
if(complaintDeptId !=0){
var reqData={"complaintDeptId":complaintDeptId};
if (complaintList.is(':empty')){
complaintList.jqGrid({
url: "./getComplaintDetails",
datatype: "json",
mtype: "POST",
ajaxGridOptions: { contentType: 'application/json' },
postData:JSON.stringify(reqData),
colNames: ['ComplaintId',"ComplaintText", ""+complaintDeptName+"", "Status",'ComplaintAdded','ComplaintUpdated','userId'],
colModel: [
{ name: "complaintId",hidden:true},
{ name: "complaintText", width:700},
{ name: "deptName", width:100},
{ name: "comstatus", width:100 },
{ name: "comAdded", width:200 },
{ name: "comUpdated", width:200 },
{ name: "userId",hidden:true },
],
pager: "#pager",
rownumbers:true,
rowNum: 5,
rowList: [5, 10, 20],
viewsortcols:[true,'vertical',true],
viewrecords: true,
gridview: true,
caption: "Complaints grid",
loadonce:true,
autowidth:true,
shrinkToFit:true,
ignoreCase: true,
height:'auto',
jsonReader: {
repeatitems: false,
id: "complaintId",
root: function (obj) { return obj; },
page: function (obj) { return 1; },
total: function (obj) { return 1; },
records: function (obj) { return obj.length; }
},
loadComplete:function(response){
/*
if (this.p.datatype === 'json') {
console.log('inside');
setTimeout(function() {
console.log('inside');
$("#list")[0].triggerToolbar();
}, 100);
}*/
complaintList.navGrid('#pager',{add:false,edit:false,refresh:true,del:false,
view:true,search:true});
complaintList.jqGrid('filterToolbar',{searchOnEnter:false,stringResult:true,defaultSearch: "cn"});
},
});
}
else{
complaintList.jqGrid('setGridParam',{postData:JSON.stringify(reqData),datatype:'json'}).trigger("reloadGrid");
complaintList.jqGrid('setLabel','deptName',complaintDeptName);
}
Here complaintList is the grid. I am getting data from the server whose type is JSON and converting into local type by using loadonce: true attribute. I want to enable client toolbar filtering
Edit to put initialization of navgrid and toolbar inside loadcomplete as grid is initialized again and again depending on the value of a paramete complaintDeptId
It I correctly understand your problem, then you should replace the parameter
postData:JSON.stringify(reqData)
to the following callback function
serializeGridData: function (postData) {
return JSON.stringify(reqData);
}
It will replace the standard data, which will be sent to the server with your custom string JSON.stringify(reqData). On the other side the standard parameter postData will stay object.
You should remove postData:JSON.stringify(reqData) from parameters of setGridParam too. serializeGridData will use the value of reqData automatically.
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.