Глобальный поиск DataTable, столбцы которого содержат поля выбора

У меня есть DataTable (с использованием DataTables 1.10.12), в котором все столбцы содержат элементы формы. 3 столбца содержат поля выбора. При использовании поля глобального поиска оно работает должным образом для столбцов, содержащих элементы input или textarea, но столбцы, содержащие поля выбора, не фильтруются должным образом.

Например, учитывая приведенную ниже таблицу, если я ввожу в поле поиска значение internal, я ожидаю, что вторая строка будет отфильтрована, поскольку значение в столбце Scope не является внутренним.

Однако никакие строки не отфильтровываются. Я понимаю, что это потому, что td на самом деле содержит слово internal в форме невыбранного параметра.

введите здесь описание изображения

Для фильтрации этих столбцов я использую такие функции:

        /* Create an array with the values of all the select options in a column */
        $.fn.dataTable.ext.order['dom-select'] = function  ( settings, col )
        {
            return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
                return $('select', td).val();
            } );
        }

Как заставить глобальное поле поиска использовать ту же логику для поиска в столбцах, содержащих поля выбора?

Мне известно о возможности добавления полей поиска отдельных столбцов с пользовательской логикой с помощью API поиска, но мне нужно, чтобы это работало с глобальным поиском, а не с отдельными столбцами.

Вот jsFiddle, показывающий проблему


person Wesley Smith    schedule 17.08.2016    source источник
comment
какую версию datatables вы используете? Ресурсы скрипки для таблиц данных не найдены.   -  person chirag    schedule 17.08.2016
comment
@chirag DataTables 1.10.12   -  person Wesley Smith    schedule 17.08.2016
comment
Вы хотите, чтобы таблица перерисовывалась каждый раз при изменении одного из вариантов? то есть вы ищете внутренний, и пользователь меняет область действия с внутреннего на общий. Это заставляет перерисовывать?   -  person Brian Kates    schedule 17.08.2016
comment
@BrianKates хороший вопрос, я не думал об этом, но теперь, когда вы упомянули об этом, и теперь, когда у меня работает поиск, да, мне нужно будет повторно применить поиск и принудительно перерисовать при изменении выбора. Спасибо что подметил это   -  person Wesley Smith    schedule 18.08.2016


Ответы (3)


Благодаря @annoyingmouse я смог разработать решение, которое позволяет искать выбранные значения в полях выбора, сохраняя при этом обычные функции поиска для всех других столбцов:

Рабочий jsFiddle

$.fn.dataTable.ext.search.push(
   function(settings, data, dataIndex) {
      var tdValues=[];
      var $tds=table.row(dataIndex).nodes().to$().find('td');
      $tds.each(function(){
         var $this=$(this);
         var hasSelect=$this.find('select').length >0; // check if current cell has a select box
         var curTdValue= hasSelect ? $this.find('option:selected').text() : $this.text();
         tdValues.push(curTdValue);
      });
      var rowValues=tdValues.join(' ');
      return !!~rowValues.toLowerCase().indexOf(table.search().toLowerCase()); 
   }     
);
person Wesley Smith    schedule 18.08.2016
comment
Отличный материал @DelightedD0D, рад, что помог. Просто хотелось бы, чтобы я мог найти способ изменить тип, чтобы он работал с собственным поиском ... ах, хорошо. Отличная работа! :-) - person annoyingmouse; 18.08.2016
comment
@annoyingmouse Кажется, это работает, как и ожидалось, однако, судя по вашим комментариям, я чувствую, что здесь мне не хватает ключевого момента. По общему признанию, я не уверен, что именно происходит с .ext.search.push. Не могли бы вы объяснить, что вы подразумеваете под изменить тип, чтобы он работал с нативным поиском? - person Wesley Smith; 18.08.2016
comment
Думаю, я хотел заменить тип в столбце — почти так же, как это делают плагины в DataTables — вместо того, чтобы заменить поиск. Вроде бы я, а потом и вы заменили функционал поиска, а не добавили к нему метод. Мне нужно еще немного почесать голову над этим, потому что я так долго не отвечал, потому что пробовал разные способы сделать это. Эй, если это работает, тогда это соус... мой метод не так элегантен, как я надеялся... - person annoyingmouse; 18.08.2016
comment
@annoyingmouse попался. Пока все хорошо, но я буду использовать это примерно на 20 разных столах, поэтому, если появятся какие-либо недостатки, я обязательно вернусь и упомяну их. - person Wesley Smith; 18.08.2016

Это заставило меня почесать голову на этот раз :-)

Я придумал это (JSFiddle):

$.fn.dataTable.ext.search.push(
   function(settings, data, dataIndex) {
      var dataLabel = table
      .row(dataIndex)         //get the row to evaluate    
      .nodes()                //extract the HTML - node() does not support to$     
      .to$()                  //get as jQuery object 
      .find('select')         //find column with data-label
      .val();                 //get the value of data-label
      return !!~dataLabel.toLowerCase().indexOf(table.search().toLowerCase()); 
   }     
);

НО, он заменяет любой другой поиск, и меня это не устраивает. Пожалуйста, не принимайте это как правильный ответ и подождите, пока кто-нибудь не придумает что-то лучше, поскольку я уверен, что кто-то может!

Жду решения!

person annoyingmouse    schedule 17.08.2016
comment
Вы потрясающий человек, который дал мне старт, который мне был нужен для разработки решения, которое я разместил здесь, чтобы, надеюсь, помочь другим. БЛАГОДАРЮ ВАС!! - person Wesley Smith; 18.08.2016

Хорошо, почесал голову, но имейте в виду, что это некрасиво:

(function() {
  $.fn.dataTable.ext.type.search.selected = function(data) {
    return !$(data).is("select") ? '' : $(data).val();
  };
})();
var table = $('#example').DataTable({
  "columnDefs": [{
    "orderDataType": "dom-select",
    "type": "selected",
    "targets": 2
  }]
});
/* Create an array with the values of all the select options in a column */
$.fn.dataTable.ext.order['dom-select'] = function(settings, col) {
  return this.api().column(col, {
    order: 'index'
  }).nodes().map(function(td, i) {
    return $('select', td).val();
  });
}
$("#example select").on("change", function() {
  var $this = $(this),
    index = null;
  var tableRow = table.row($this.parents('tr'));
  var rowDate = tableRow.data();
  $.each(rowDate, function(k, v) {
    if (v === $this.prop("outerHTML")) {
      index = k;
    }
  });
  var newRowData = rowDate.slice(0);
  var tempSelect = $(newRowData[index]);
  tempSelect.find("option[value!='" + $this.val() + "']").removeAttr("selected");
  tempSelect.find("option[value='" + $this.val() + "']").attr("selected", "selected");
  newRowData[index] = tempSelect.prop("outerHTML");
  table.row($(this).parents('tr')).data(newRowData).draw(true);
});

Поэтому мы сохраняем вашу функцию сортировки и добавляем тип selected в соответствующий столбец. Поиск selected возвращает значение выбора, но возвращает значение только при инициализации таблицы.

Чтобы обойти это, мы прослушиваем изменения на входах select в таблице, получаем данные из строки, копируем их, манипулируем копией и заменяем ее в исходной позиции, затем снова рисуем таблицу. Затем мы можем искать новое значение.

Это сохраняет ванильный глобальный поиск с данными как есть, но дает ему правильные данные для поиска. Фу!!!!

Надеюсь, это поможет :-)

person annoyingmouse    schedule 18.08.2016