Поиск по фильтру столбцов jQuery Datatable не работает

Я работаю над приложением 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();
    }

Как это исправить? Я хочу отфильтровать данные при нажатии кнопки «ОК» в меню фильтра.

По моим наблюдениям, поскольку ваш DataTable обрабатывается на стороне сервера, API column(i).search() также будет обрабатываться на стороне сервера, что означает, что поиск данных выполняется на стороне сервера, а не на стороне внешнего интерфейса. Поэтому вам необходимо передать правильные критерии поиска в функцию data, и ваш API необходим для реализации логики поиска.

Yong Shun 22.08.2024 03:52

Кроме того, что, если пользователь попытается фильтровать по нескольким столбцам на основе вашего API, я вижу, что он принимает фильтр только по одному столбцу.

Yong Shun 22.08.2024 03:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
151
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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. Еще один момент: после фильтрации при нажатии на значок фильтра флажок будет установлен для уже отфильтрованного элемента. Не могли бы вы посмотреть на эти вопросы?? Большое спасибо.

KitKat 23.08.2024 13:30

Привет @XieMan, в моем вопросе есть еще одна проблема: в контроллере DOOR_MANAGEMENT есть метод LoadDoors. Существует аргумент с именем «FilterByColumn», и он нам нужен для сортировки столбца DataTable. Пожалуйста, учтите и это.

KitKat 23.08.2024 13:42

Я редактирую свой ответ. Вы можете изменить только функцииclearFilter и PerformFilter. 1. Когда вызывается метод draw, вы создаете диалоговое окно anthor modalFilter, поэтому вы устанавливаете флажок, который не работает, поэтому после того, как мы его уничтожим, мы должны удалить все modalFilter html. 2.Я думаю, что после фильтрации критерии изменились, поэтому нет необходимости выбирать их все. И3. не высказывайте свою идею, потому что я думаю, что ваш проект должен использовать базу данных, вы можете легко использовать сортировку sql. вы можете увидеть:Learn.microsoft.com/en-us/sql/t-sql/queries/…

XieMan 26.08.2024 05:19

Привет @XieMan. Спасибо за ваш ответ. Но это не работает для фильтрации более одного значения столбца. Предположим, я открыл меню фильтрации «Код бренда», отметил «NB» и «JA», а затем нажал «ОК». Это не работает. Я попытался отфильтровать «Имя настройки» и выбрал «Настройка3» в меню фильтрации. Но это не фильтрация, как ожидалось. Будьте добры, исправьте эти проблемы. Большое спасибо за ваши усилия.

KitKat 26.08.2024 11:00
Ответ принят как подходящий
  1. Используйте массив для хранения выбранных 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, и он работает. Но флажок в меню фильтра должен быть отмечен для уже отфильтрованного элемента. Можете ли вы написать только этот код??? Просто удалите новый код выше и объясните мне, как сделать элемент, отмеченный флажком, для уже проверенных данных?? Спасибо за помощь.

KitKat 27.08.2024 16:02

Вы хотите написать логику фильтра для действия LoodDoors? Я считаю, что работать с фиксированными данными слишком сложно, обычно мы работаем с данными из баз данных.

XieMan 27.08.2024 17:07

Привет @XieMan, спасибо, твой код теперь работает. Но 1 небольшая проблема. При фильтрации столбца «tracking_weeks» состояние флажка не сохраняется, если оно уже отфильтровано. Но другие колонки работают нормально. Что случилось с «tracking_weeks»?

KitKat 27.08.2024 17:56

Вы можете проверить, соответствует ли тип данных, будь то строка или число, а затем преобразовать его.

XieMan 27.08.2024 18:44

Другие вопросы по теме