Я работаю над приложением ASP.Net Core MVC C# (Visual Studio 2022), и оно использует таблицу данных jQuery. Я использую вызов ajax для загрузки данных из базы данных. В заголовке каждого столбца в таблице данных есть значок фильтра, при нажатии на который открывается меню фильтров, содержащее данные столбца с флажком, как показано ниже.
[![][1]][1]
Проблема заключается в том, что при выборе одного или нескольких флажков в меню фильтра и нажатии кнопки «ОК» таблица данных должна фильтровать данные в ней. Но в моем коде не работает поиск по фильтру. Вот код, который я использую в своем приложении ASP.Net Core MVC.
В Index.cshtml:
@model AMD_WEB.Models.DoorDetails
@{
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, 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 = [];
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()[columnIdx];
var data = this.data()[propertyName];
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>
В классе контроллера DOOR_MANAGEMENT метод загрузки данных показан ниже:
public IActionResult LoadDoors(int draw = 1, int start = 0, int length = 10, string search = "", string FilterByColumn = "", string ASC_DSEC = "")
{
List<DoorDetails> ListData = new List<DoorDetails>();
int recordsTotal = 0;
DateTime aDate = DateTime.Now;
DoorDetails dm = new DoorDetails();
dm.door_id = 1;
dm.brand = "BM";
dm.buying_group = "Silly USA";
dm.setting_name = "Settings1";
dm.datamodel = 13;
dm.tracking_weeks = 1;
DoorDetails dm1 = new DoorDetails();
dm1.door_id = 2;
dm1.brand = "NB";
dm1.buying_group = "John USA";
dm1.setting_name = "Settings2";
dm1.datamodel = 16;
dm1.tracking_weeks = 14;
DoorDetails dm11 = new DoorDetails();
dm11.door_id = 3; ;
dm11.brand = "JA";
dm11.buying_group = "Mathew 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);
}
Класс модели DoorDetails показан ниже:
namespace AMD_WEB.Models
{
public class DoorDetails
{
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; }
}
}
Проблема заключается в следующем разделе кода:
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(); // HERE SEARCH IS NOT WORKING
rootNode.hide();
$('#mask').hide();
}
Как это исправить? Я хочу отфильтровать данные при нажатии кнопки «ОК» в меню фильтра.
Кроме того, что, если пользователь попытается фильтровать по нескольким столбцам на основе вашего API, я вижу, что он принимает фильтр только по одному столбцу.





1.Draw метод не работает, мы показываем destory таблицу, а затем инициализируем таблицу.
2."searchString" не может быть передано в метод, потому что нет поля для получения. Я определяю две переменные для передачи параметров.
Я копирую ваш код и встречаю некоторые проблемы. Я не знаю, есть ли у вас такая же проблема, поэтому я комментирую все свои изменения. Я надеюсь, что это поможет вам.
контроллер.cs:
public IActionResult LoadDoors( string FilterStrings, string FilterOrder= "")//filter from colum require two params,
{
List<DoorDetails> ListData = new List<DoorDetails>();
int recordsTotal = 0;
DateTime aDate = DateTime.Now;
DoorDetails dm = new DoorDetails();
dm.door_id = 1;
dm.brand = "BM";
dm.buying_group = "Silly USA";
dm.setting_name = "Settings1";
dm.datamodel = 13;
dm.tracking_weeks = 1;
DoorDetails dm1 = new DoorDetails();
dm1.door_id = 2;
dm1.brand = "NB";
dm1.buying_group = "John USA";
dm1.setting_name = "Settings2";
dm1.datamodel = 16;
dm1.tracking_weeks = 14;
DoorDetails dm11 = new DoorDetails();
dm11.door_id = 3; ;
dm11.brand = "JA";
dm11.buying_group = "Mathew UK";
dm11.setting_name = "Settings3";
dm11.datamodel = 17;
dm11.tracking_weeks = 45;
ListData.Add(dm);
ListData.Add(dm1);
ListData.Add(dm11);
//this code to processing data filter by page
if (!string.IsNullOrEmpty(FilterStrings)) {
for (int i = 0; i < ListData.Count(); i++)
{
Console.Write(FilterStrings.Contains(ListData[i].GetType().GetProperty(FilterOrder)?.GetValue(ListData[i])?.ToString() ?? ""));
if (!FilterStrings.Contains(ListData[i].setting_name))
{
ListData.Remove(ListData[i]);
}
}
}
recordsTotal = ListData.Count();
var jsonData = new
{
draw = 1,
recordsFiltered = recordsTotal,
recordsTotal = recordsTotal,
data = ListData
};
return Ok(jsonData);
}
.cshtml:
@model WebApplication1.Models.DoorDetails
@{
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=https://code.jquery.com/jquery-3.7.1.js></script>
<script src=https://cdn.datatables.net/1.10.12/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;
background: red; /* have no icon */
}
.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>
var searchStr = "";//store the selected checkbox value
var myDataTable = {};//store the initialize table
var orderColumn = ''//selected column for custom filter
$(document).ready(function () {
resetDataTable();//initialize table
$('#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 = "javascript:;" 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 = [];
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()[columnIdx];
var data = this.data()[propertyName];
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) {
searchStr = ""; //clear
orderColumn = "";//clear
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++;
}
});
var columnMapping = {
0: 'brand',
1: 'buying_group',
2: 'setting_name',
3: 'sites',
4: 'tracking_weeks'
};
orderColumn = columnMapping[i];//set value
searchStr = rootNode.find('.filterSearchText').val()||searchString;//set value
myDataTable.destroy();//destory table
$('#example').empty();//clear talbe in html
$('.modalFilter').remove();//remove all the modalFilter
resetDataTable();//initialize table
rootNode.hide();
$('#mask').hide();
}
//initialize table method
function resetDataTable() {
myDataTable = $("#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: '@Url.Action("LoadDoors", "Home")',// your method is doesn't work,So I use this.
//URL: "/Home/LoadDoors"
type: 'GET',
datatype: 'json',
headers: { 'RequestVerificationToken': 'your json token' },
data: (d) => {
console.info(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, FilterStrings: searchStr, FilterOrder: orderColumn }
},
//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, 4]);
}
});// datatable
}
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();
});
var columnMapping = {
0: 'brand',
1: 'buying_group',
2: 'setting_name',
3: 'sites',
4: 'tracking_weeks'
};
orderColumn = columnMapping[i];//set value
searchStr = '' || rootNode.find('.filterSearchText').val()//set value
myDataTable.destroy();//destory table
$('#example').empty();//clear talbe in html
$('.modalFilter').remove();//remove all the modalFilter
resetDataTable();//initialize table
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>
Результаты:
Привет @XieMan Спасибо за помощь. Но фильтр работает только первый раз. После этого он не работает. Начиная со второго раза, при попытке отфильтровать любой другой столбец, даже я не могу установить флажки в меню фильтров. В меню фильтра установите более 1 флажка и нажмите «ОК», таблица данных не фильтруется. Также не работает кнопка CLEAR. Еще один момент: после фильтрации при нажатии на значок фильтра флажок будет установлен для уже отфильтрованного элемента. Не могли бы вы посмотреть на эти вопросы?? Большое спасибо.
Привет @XieMan, в моем вопросе есть еще одна проблема: в контроллере DOOR_MANAGEMENT есть метод LoadDoors. Существует аргумент с именем «FilterByColumn», и он нам нужен для сортировки столбца DataTable. Пожалуйста, учтите и это.
Я редактирую свой ответ. Вы можете изменить только функцииclearFilter и PerformFilter. 1. Когда вызывается метод draw, вы создаете диалоговое окно anthor modalFilter, поэтому вы устанавливаете флажок, который не работает, поэтому после того, как мы его уничтожим, мы должны удалить все modalFilter html. 2.Я думаю, что после фильтрации критерии изменились, поэтому нет необходимости выбирать их все. И3. не высказывайте свою идею, потому что я думаю, что ваш проект должен использовать базу данных, вы можете легко использовать сортировку sql. вы можете увидеть:Learn.microsoft.com/en-us/sql/t-sql/queries/…
Привет @XieMan. Спасибо за ваш ответ. Но это не работает для фильтрации более одного значения столбца. Предположим, я открыл меню фильтрации «Код бренда», отметил «NB» и «JA», а затем нажал «ОК». Это не работает. Я попытался отфильтровать «Имя настройки» и выбрал «Настройка3» в меню фильтрации. Но это не фильтрация, как ожидалось. Будьте добры, исправьте эти проблемы. Большое спасибо за ваши усилия.
checkbox и столбца, затем нам нужно отредактировать showFilter,performFilter,clearFilter три
функции, добавьте параметр массива в функцию Action in resetDataTable. Я переверну весь код на случай, если чего-то не хватает:
вот код скрипта:
<script>
var searchStr = "";//store the selected checkbox value
var myDataTable = {};//store the initialize table
var orderColumn = ''//selected column for custom filter
var filterArr = [];//store checkbox and column
var columnMapping = {
0: 'brand',
1: 'buying_group',
2: 'setting_name',
3: 'sites',
4: 'tracking_weeks'
};
$(document).ready(function () {
resetDataTable();//initialize table
$('#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 = "javascript:;" 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 = [];
var propertyName = columnMapping[columnIdx];
table.rows({ search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop) {
//var data = this.data()[columnIdx];
var data = this.data()[propertyName];
var searchStr = "";
var searchArr = [];
console.info(filterArr);
filterArr.forEach(function(item){
if (item.column == propertyName) {
searchStr = item.searchStr;
}
})
if (searchStr.indexOf('|') < 0) {
searchArr = [searchStr]
} else {
searchArr = searchStr.split("|")
}
if (distinctArray.indexOf(data) == -1) {
var id = index + "_" + rowIdx;
if (searchArr.indexOf(data) >= 0) {
content += '<div><input checked type = "checkbox" value = "' + data + '" id = "' + id + '"/><label for = "' + id + '" > ' + data + '</label></div>';
} else {
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) {
orderColumn = columnMapping[i];//set value
searchStr = ""; //clear
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++;
}
});
searchStr = rootNode.find('.filterSearchText').val()||searchString;//set value
var isIn = false
filterArr.forEach( function (item, index) {//exsit
if (item.column == orderColumn) {
item.searchStr = searchStr;
isIn = true;
}
})
if (!isIn) {
filterArr.push({
column: orderColumn,
searchStr: searchStr
})
}
console.info(filterArr);
myDataTable.destroy();//destory table
$('#example').empty();//clear talbe in html
$('.modalFilter').remove();//remove all the modalFilter
resetDataTable();//initialize table
rootNode.hide();
$('#mask').hide();
}
//initialize table method
function resetDataTable() {
myDataTable = $("#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: '@Url.Action("LoadDoors", "Home")',// your method is doesn't work,So I use this.
//URL: "/Home/LoadDoors"
type: 'POST',
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, filterArr: filterArr }
},
// 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, 4]);
}
});// datatable
}
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();
});
orderColumn = columnMapping[i];//set value
searchStr = '' || rootNode.find('.filterSearchText').val()//set value
filterArr.forEach(function (item, index) {//exsit
if (item.column == orderColumn) {
item.searchStr = "";
}
})
myDataTable.destroy();//destory table
$('#example').empty();//clear talbe in html
$('.modalFilter').remove();//remove all the modalFilter
resetDataTable();//initialize table
rootNode.hide();
$('#mask').hide();
}
</script>
2. Данные процесса действия. 1). Создайте модель filterArr:
public class filterArr
{
public string column { get; set; }
public string searchStr { get; set; }
}
2).Действие (ваш проект должен использовать базу данных, поэтому я не пишу логику обработки, вы можете увидеть:https://learn.microsoft.com/en-us/sql/t-sql/queries/where- transact-sql?view=sql-server-ver16 ):
public IActionResult LoadDoors(List<filterArr> filterArr,string FilterByColumn = "")//filter from colum require two params,
{
string result = Newtonsoft.Json.JsonConvert.SerializeObject(filterArr);
for (int i = 0; i < filterArr.Count(); i++)
{
Console.Write(filterArr[i].column);
}
List<DoorDetails> ListData = new List<DoorDetails>();
int recordsTotal = 0;
DateTime aDate = DateTime.Now;
DoorDetails dm = new DoorDetails();
dm.door_id = 1;
dm.brand = "BM";
dm.buying_group = "Silly USA";
dm.setting_name = "Settings1";
dm.datamodel = 13;
dm.tracking_weeks = 1;
DoorDetails dm1 = new DoorDetails();
dm1.door_id = 2;
dm1.brand = "NB";
dm1.buying_group = "John USA";
dm1.setting_name = "Settings2";
dm1.datamodel = 16;
dm1.tracking_weeks = 14;
DoorDetails dm11 = new DoorDetails();
dm11.door_id = 3; ;
dm11.brand = "JA";
dm11.buying_group = "Mathew UK";
dm11.setting_name = "Settings3";
dm11.datamodel = 17;
dm11.tracking_weeks = 45;
ListData.Add(dm);
ListData.Add(dm1);
ListData.Add(dm11);
recordsTotal = ListData.Count();
var jsonData = new
{
draw = 1,
recordsFiltered = recordsTotal,
recordsTotal = recordsTotal,
data = ListData
};
return Ok(jsonData);
}
Результат:
Привет @XieMan. Фильтрация вообще не работает с этим новым кодом. Я заставил это работать с вашим предыдущим ответом. Фильтрация работает с предыдущим кодом. Я только что изменил код в методе LoadDoors, и он работает. Но флажок в меню фильтра должен быть отмечен для уже отфильтрованного элемента. Можете ли вы написать только этот код??? Просто удалите новый код выше и объясните мне, как сделать элемент, отмеченный флажком, для уже проверенных данных?? Спасибо за помощь.
Вы хотите написать логику фильтра для действия LoodDoors? Я считаю, что работать с фиксированными данными слишком сложно, обычно мы работаем с данными из баз данных.
Привет @XieMan, спасибо, твой код теперь работает. Но 1 небольшая проблема. При фильтрации столбца «tracking_weeks» состояние флажка не сохраняется, если оно уже отфильтровано. Но другие колонки работают нормально. Что случилось с «tracking_weeks»?
Вы можете проверить, соответствует ли тип данных, будь то строка или число, а затем преобразовать его.
По моим наблюдениям, поскольку ваш DataTable обрабатывается на стороне сервера, API
column(i).search()также будет обрабатываться на стороне сервера, что означает, что поиск данных выполняется на стороне сервера, а не на стороне внешнего интерфейса. Поэтому вам необходимо передать правильные критерии поиска в функциюdata, и ваш API необходим для реализации логики поиска.