【问题标题】:Search within input and select在输入中搜索并选择
【发布时间】:2015-08-20 15:29:43
【问题描述】:

我在应用程序中设置了一个数据表,其中行包含输入字段,并且我根据输入字段的文本值对表进行排序和过滤。我设法让排序正常工作,但我一辈子都无法让搜索工作。我认为问题与该表是由另一个在调用数据表之前运行的 JavaScript 动态生成和填充的事实有关。

这是目前的 JavaScript:

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

    /* Create an array with the values of all the input boxes in a column, parsed as numbers */
    $.fn.dataTable.ext.order["dom-text-numeric"] = function  ( settings, col )
    {
        return this.api().column( col, {order:"index"} ).nodes().map( function ( td, i ) {
            return $("input", td).val() * 1;
        } );
    }

    /* 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();
        } );
    }


        $(document).ready(function() {

        var table =  $("#service_group0").DataTable({
                "searching": true,
                "ordering":  true,
                "columns": [
                    { "orderDataType": "dom-text", type: \'html\' },
                    { "orderDataType": "dom-select",type: \'html\' },
                    { "orderDataType": "dom-text" , type: \'string\'},
                    { "orderDataType": "dom-text", type: \'string\' },
                    { "orderDataType": "dom-text", type: \'string\'},
                    { "orderDataType": "dom-select" },
                    { "orderDataType": "dom-select" },
                    { "orderDataType": "dom-text-numeric"},
                   { "orderDataType": "dom-text", type: \'date\'},
                    null,
                    { "orderDataType": "dom-select" },
                    { "orderDataType": "dom-text-numeric"},
                    { "orderDataType": "dom-select" },
                    { "orderDataType": "dom-text", type: \'string\' },
                    { "orderDataType": "dom-text", type: \'string\' },
                    { "orderDataType": "dom-text", type: \'date\'},
                    null,
                    null
                ],
                initComplete:   function () {
                    this.api().columns().every( function () {
                        var column = this;
                         if(column.index() == 5){
                            var select = $("<select id=\'strength_search\'></select>")
                                .appendTo( $(column.footer()).empty());
                                var strength_hidden = document.getElementById("strength_hidden").value;
                                select.append(strength_hidden);
                        }
                        else if(column.index() == 6){
                             var select = $("<select id=\'dose_search\'></select>")
                                .appendTo( $(column.footer()).empty());
                                var dose_hidden = document.getElementById("dose_hidden").value;
                                select.append(dose_hidden);
                        }
                    });
                }
            });

这里要粘贴的 html 太多了,所以我创建了一个 jsfiddle:http://jsfiddle.net/q715LncL/12/

如果您转到 jsfiddle 并在空文本字段中输入内容,然后转到搜索框并尝试根据您输入的内容进行过滤,它总是不会返回任何结果。如何让它过滤对实时输入所做的更改?

【问题讨论】:

    标签: javascript jquery datatables


    【解决方案1】:

    您需要添加一个自定义过滤函数来检查输入框的值,DataTables 将 HTML 转换为字符串,您无法从中恢复实时值,因此您必须执行以下操作:

    $.fn.dataTable.ext.search.push(
        function( settings, data, dataIndex ) {
          var searchTerm = $('.dataTables_filter input').val();
          var $row = $('.dataTable tbody tr').eq(dataIndex);
    
          if(!searchTerm) {
            return true;
          }
    
          return $row.find('td input').filter(function() {
            return ~$(this).val().toLowerCase().indexOf(searchTerm.toLowerCase())
          }).size();
        }
    );
    

    http://jsfiddle.net/q715LncL/14/

    【讨论】:

    • 谢谢我看看这个,顺便说一句,你的 js fiddle 似乎对我不起作用。如果我将 test 放入其中一个品牌名称字段并将 abc 放入另一个然后在搜索框中输入 test 它不会找到该行。
    【解决方案2】:

    解决方案

    您可以使用columnDefs 在targets 选项中使用从零开始的索引来定位特定列,并使用render 在搜索(type === 'filter')或排序(type === 'order')期间返回选定的值。

    columnDefs: [
       { 
          targets: [0,1,2,3,4,5,6], 
          render: function(data, type, full, meta){
             if(type === 'filter' || type === 'sort'){
                var api = new $.fn.dataTable.Api(meta.settings);
                var td = api.cell({row: meta.row, column: meta.col}).node();
                data = $('select, input', td).val();
             }
    
             return data;
          }
       }
    ]
    

    此外,一旦数据发生更改,您需要使单元格数据失效,如下所示(根据this solution)。

    $('tbody select, tbody input', table.table().node()).on('change', function(){
         table.row($(this).closest('tr')).invalidate();
    });  
    

    演示

    有关代码和演示,请参阅 this jsFiddle。

    注意事项

    我已经注释了由于不存在的元素而导致 JavaScript 错误的代码。

    【讨论】:

    • 感谢这有很大帮助,并且似乎在大多数情况下都有效,但是当我在实际应用程序中使用它时,如果我在输入字段中加载具有值的行,它似乎会清除它们。我不确定我是否完全理解您的代码是如何工作的。当表由其他脚本动态生成和填充时,某些行中已经包含数据,因此它需要同时使用这两者并允许在输入字段中使用实时和现有日期进行排序。
    • @user794846,你是对的,由于某种原因,它不适用于新添加的行。我需要研究它并更新答案。
    • 感谢您整个上午都在为此苦苦挣扎,但并没有走得太远
    • 对不起,它不是新添加的行,它添加的行已经用值填充了输入字段。它使它们空白。
    猜你喜欢
    • 2015-03-07
    • 2015-11-14
    • 1970-01-01
    • 2013-08-12
    • 2015-02-23
    • 1970-01-01
    • 2019-10-25
    • 2021-11-22
    • 1970-01-01
    相关资源
    最近更新 更多