Меню фильтра не работает с jQuery DataTable

Я динамически загружаю данные в таблицу данных 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.**
  .........................

Пожалуйста, помогите мне.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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
0
111
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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 }
],

Привет @Rena. Неопределенная ошибка исчезла, и я могу перечислить меню фильтров с правильными данными. Спасибо. Но проблема в том, что когда я установил флажок и нажал «ОК», таблица данных не фильтруется. После нажатия ОК в меню фильтров ничего не происходит. Не могли бы вы это проверить и решить?

KitKat 20.08.2024 12:09

Привет @KitKat, я думаю, это должен быть новый выпуск. Что касается политики SO, я предлагаю вам опубликовать новую тему с подробным кодом и пояснениями.

Rena 21.08.2024 03:42

Привет @Рена. Спасибо за помощь. Но я разместил новый вопрос по фильтрации данных здесь stackoverflow.com/questions/78898051/…. Пожалуйста, помогите мне.

KitKat 21.08.2024 18:27

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