Я динамически загружаю данные в таблицу данных jQuery, используя метод ajax. Меню фильтра раскрывается при нажатии на значок фильтра в заголовке столбца данных и всегда показывает «неопределено». Этот проект представляет собой приложение ASP.Net Core MVC C#. Код показан ниже:
@model 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,
lengthMenu: [[5, 10, 50, -1], [5, 10, 50, "All"]],
language: { searchPlaceholder: "Brand, 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 = "http://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>
И метод в контроллере показан ниже:
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 = "SEPHIA 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 = "JOHN 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 = "Elms UK";
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);
}
Модель DOOR_MANAGEMENT показана ниже:
public class DOOR_MANAGEMENT
{
public int DOOR_ID { get; set; }
public string BRAND { get; set; }
public string BUYING_GROUP { get;set; }
public string SETTING_NAME { get;set; }
public int? DATAMODEL { get;set; }
public int? TRACKING_WEEKS { get;set;}
}
Приведенный выше код будет работать, если он жестко запрограммирован DataSet. Но при динамической загрузке данных из базы данных как List<DOOR_MANAGEMENT>( ), в меню фильтра отображается «не определено».
Я разобрался с местом выдачи:
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];
alert(data); **// HERE IS THE PROBLEM. Data is undefined.**
.........................
Пожалуйста, помогите мне.
this.data()
возвращает объект, и вам необходимо динамически получать доступ к его свойствам на основе индекса столбца. Вам нужно сопоставить индекс столбца с соответствующим именем свойства.
Измените свой вариант ниже:
var columnMapping = {
0: 'brand',
1: 'buyinG_GROUP',
2: 'settinG_NAME',
3: 'sites',
4: 'trackinG_WEEKS'
};
var propertyName = columnMapping[columnIdx];
table.rows({ search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop) {
var data = this.data()[propertyName];
alert(data);
Имя свойства зависит от полученного вами ответа в формате JSON. Пожалуйста, проверьте свой ответ в формате JSON ниже:
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>';
}
console.info(json); //F12 in the browser and check the Console panel
return json;
}
Ответ json на моей стороне выглядит следующим образом:
DataTable в ядре asp.net отображает данные json с помощью строчной начальной буквы по умолчанию, поэтому также необходимо изменить столбцы, как показано ниже:
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 }
],
Привет @KitKat, я думаю, это должен быть новый выпуск. Что касается политики SO, я предлагаю вам опубликовать новую тему с подробным кодом и пояснениями.
Привет @Рена. Спасибо за помощь. Но я разместил новый вопрос по фильтрации данных здесь stackoverflow.com/questions/78898051/…. Пожалуйста, помогите мне.
Привет @Rena. Неопределенная ошибка исчезла, и я могу перечислить меню фильтров с правильными данными. Спасибо. Но проблема в том, что когда я установил флажок и нажал «ОК», таблица данных не фильтруется. После нажатия ОК в меню фильтров ничего не происходит. Не могли бы вы это проверить и решить?