I am dynamically loading data into the jQuery datatable using ajax method. The filter menu is droping down when clicking on the filter icon in datatable column header and it shows always “undefined”. This project is a ASP.Net Core MVC C# app. The code is shown below:
@model LMD_WEB.Models.DOOR_MANAGEMENT
@{
ViewData["Title"] = "Index";
}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css" type="text/css" rel="stylesheet" media="screen,projection" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.min.css" />
<script src="~/js/jquery-2.2.4.min.js"></script>
<script src="~/js/jquery.datatables.min.js"></script>
<script src="~/js/materialize.min.js"></script>
<style>
table.dataTable th {
border-bottom: 1px solid #333;
border-right: 1px solid #333;
}
table.dataTable td {
border-bottom: 1px solid #333;
border-right: 1px solid #333;
}
.filterIcon {
height: 16px;
width: 16px;
}
.modalFilter {
display: none;
height: auto;
background: #FFF;
border: solid 1px #ccc;
padding: 8px;
position: absolute;
z-index: 1001;
}
.modalFilter .modal-content {
max-height: 250px;
overflow-y: auto;
}
.modalFilter .modal-footer {
background: #FFF;
height: 35px;
padding-top: 6px;
}
.modalFilter .btn {
padding: 0 1em;
height: 28px;
line-height: 28px;
text-transform: none;
}
#mask {
display: none;
background: transparent;
position: fixed;
left: 0;
top: 0;
z-index: 1;
width: 100%;
height: 100%;
opacity: 1000;
}
</style>
<script>
$(document).ready(function (){
$("#example").DataTable({
serverSide: true,
sortable: true,
filter: true,
searchDelay: 1000,
scrollY: StaticData.TABLE_HEIGHT + 'px',
lengthMenu: [[5, 10, 50, -1], [5, 10, 50, "All"]],
language: { searchPlaceholder: "Brand Code, Buying Group" },
scrollCollapse: true,
ajax: {
url: '/DOOR_MANAGEMENT/LoadDoors',
type: 'GET',
datatype: 'json',
headers: { 'RequestVerificationToken': 'your json token' },
data: (d) => {
return { draw: d.draw, start: d.start, length: d.length, search: d.search.value, FilterByColumn: d.columns[d.order[0].column].data, ASC_DSEC: d.order[0].dir }
},
beforeSend: () => { ShowLoader(); },
complete: () => { HideLoader(); },
dataSrc: (json) => {
json = json.data;
for (var i = 0, ien = json.length; i < ien; i++) {
json[i]['sites'] = '<button style="height:25px;width:60px"> Site </button>';
}
return json;
}
},
columnDefs: [{ className: "dt-center", targets: [1,2,3] }],
columns: [
{ data: 'DOOR_ID', title: 'DOOR ID', autoWidth: false, visible: false },
{ data: 'BRAND', title: 'Brand Code', autoWidth: true, searchable: true },
{ data: 'BUYING_GROUP', title: 'Buying Group', autoWidth: true },
{ data: 'SETTING_NAME', title: 'Setting Name', autoWidth: true },
{ data: 'sites', title: 'Site(s)', autoWidth: true, orderable: false },
{ data: 'TRACKING_WEEKS', title: 'Tracking Weeks', autoWidth: true }
],
initComplete: function () {
configFilter(this, [0, 1, 2, 3, 4]);
}
});// datatable
$('#example_length,#example_filter').hide();
});
function configFilter($this, colArray) {
setTimeout(function () {
var tableName = $this[0].id;
var columns = $this.api().columns();
$.each(colArray, function (i, arg) {
$('#' + tableName + ' th:eq(' + arg + ')').append('<img src="https://www.icone-png.com/png/39/38556.png" class="filterIcon" onclick="showFilter(event,'' + tableName + '_' + arg + '')" />');
});
var template = '<div class="modalFilter">' +
'<div class="modal-content">' +
'{0}</div>' +
'<div class="modal-footer">' +
'<a href="#!" onclick="clearFilter(this, {1}, '{2}');" class=" btn left waves-effect waves-light">Clear</a>' +
'<a href="#!" onclick="performFilter(this, {1}, '{2}');" class=" btn right waves-effect waves-light">Ok</a>' +
'</div>' +
'</div>';
$.each(colArray, function (index, value) {
columns.every(function (i) {
if (value === i) {
var column = this, content = '<input type="text" class="filterSearchText" onkeyup="filterValues(this)" /> <br/>';
var columnName = $(this.header()).text().replace(/s+/g, "_");
var distinctArray = [];
column.data().each(function (d, j) {
if (distinctArray.indexOf(d) == -1) {
var id = tableName + "_" + columnName + "_" + j;
content += '<div><input type="checkbox" value="' + d + '" id="' + id + '"/><label for="' + id + '"> ' + d + '</label></div>';
distinctArray.push(d);
}
});
var newTemplate = $(template.replace('{0}', content).replace('{1}', value).replace('{1}', value).replace('{2}', tableName).replace('{2}', tableName));
$('body').append(newTemplate);
modalFilterArray[tableName + "_" + value] = newTemplate;
content = '';
}
});
});
}, 50);
}
var modalFilterArray = {};
function showFilter(e, index) {
var table = $('#' + index.split('_')[0]).DataTable();
var columnIdx = parseInt(index.split('_')[1]);
var column = table.column(columnIdx);
var filterContainer = $(modalFilterArray[index]);
var content = '<input type="text" class="filterSearchText" onkeyup="filterValues(this)" /> <br/>';
var distinctArray = [];
table.rows({ search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop) {
var data = this.data()[columnIdx];
if (distinctArray.indexOf(data) == -1) {
var id = index + "_" + rowIdx;
content += '<div><input type="checkbox" value="' + data + '" id="' + id + '"/><label for="' + id + '"> ' + data + '</label></div>';
distinctArray.push(data);
}
});
filterContainer.find('.modal-content').html(content);
$('.modalFilter').hide();
var th = $(e.target).parent();
var pos = th.offset();
filterContainer.width(th.width() * 0.75);
filterContainer.css({ 'left': pos.left, 'top': pos.top }).show();
$('#mask').show();
e.stopPropagation();
}
function filterValues(node) {
var searchString = $(node).val(); //.toUpperCase().trim();
var rootNode = $(node).parent();
if (searchString == '') {
rootNode.find('div').show();
} else {
rootNode.find("div").hide();
rootNode.find("div:contains('" + searchString + "')").show();
}
}
function performFilter(node, i, tableId) {
var rootNode = $(node).parent().parent();
var searchString = '', counter = 0;
rootNode.find('input:checkbox').each(function (index, checkbox) {
if (checkbox.checked) {
searchString += (counter == 0) ? checkbox.value : '|' + checkbox.value;
counter++;
}
});
$('#' + tableId).DataTable().column(i).search(
searchString,
true, false
).draw();
rootNode.hide();
$('#mask').hide();
}
function clearFilter(node, i, tableId) {
var rootNode = $(node).parent().parent();
rootNode.find(".filterSearchText").val('');
rootNode.find('input:checkbox').each(function (index, checkbox) {
checkbox.checked = false;
$(checkbox).parent().show();
});
$('#' + tableId).DataTable().column(i).search(
'',
true, false
).draw();
rootNode.hide();
$('#mask').hide();
}
</script>
</head>
<body>
<div id="mask"></div>
<table id="example" class="bordered material-table centered striped green lighten-1">
</table>
</body>
</html>
And the method in the controller is as shown below:
public IActionResult LoadDoors(int draw = 1, int start = 0, int length = 10, string search = "", string FilterByColumn = "", string ASC_DSEC = "")
{
List<DOOR_MANAGEMENT> ListData = new List<DOOR_MANAGEMENT>();
int recordsTotal = 0;
DOOR_MANAGEMENT dm = new DOOR_MANAGEMENT();
dm.DOOR_ID = 1;
dm.BRAND = "BM";
dm.BUYING_GROUP = "SEPHORA USA";
dm.SETTING_NAME = "Settings1";
dm.DATAMODEL = 13;
dm.TRACKING_WEEKS = 1;
DOOR_MANAGEMENT dm1 = new DOOR_MANAGEMENT();
dm1.DOOR_ID = 2;
dm1.BRAND = "NB";
dm1.BUYING_GROUP = "JASSIM USA";
dm1.SETTING_NAME = "Settings2";
dm1.DATAMODEL = 16;
dm1.TRACKING_WEEKS = 14;
DOOR_MANAGEMENT dm11 = new DOOR_MANAGEMENT();
dm11.DOOR_ID = 3;
dm11.BRAND = "JA";
dm11.BUYING_GROUP = "Mano USA";
dm11.SETTING_NAME = "Settings 3";
dm11.DATAMODEL = 17;
dm11.TRACKING_WEEKS = 45;
ListData.Add(dm);
ListData.Add(dm1);
ListData.Add(dm11);
recordsTotal = ListData.Count();
var jsonData = new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = ListData };
return Ok(jsonData);
}
The above code will work if it is static dataset. But when dynamically loading data from database as List(), the filter menu shows “undefined”.
Please help me.