Column Level filter is not working when mapped with external data sources

Column Level filter is not working when mapped with external data sources

deveshmishradeveshmishra Posts: 6Questions: 1Answers: 0

Hi,

i am using external data sources to populate table. Ie want to add column level filter in table footer. Please have a look at below code snippet.

I have added text input into the footer, but search is not working. After search, it always showing zero result. Please someone help.

        var table;
        $(document).ready(function() {
            table = $('#example').DataTable({
                data: tableData,
                columns: getColumnName()
            });
            applyColumnFilter();

            function applyColumnFilter() {
                var footer = "<tfoot><tr>";
                $('#example thead th').each( function () {
                    var title = $(this).text();
                    footer+= "<th rowspan='1' colspan='1'>" + title + "</th>";
                });
                footer+= "</tr></tfoot>";
                $('#example').append(footer);

                $('#example tfoot th').each( function () {
                    var title = $(this).text();
                    $(this).html( '<input type="text" placeholder="Search '+title+'" />' );
                });

                /* Option 1 */
                /*table.columns().every( function () {
                    var that = this;
                    $( 'input', this.footer() ).on( 'keyup change', function () {
                        console.log(this.value);
                        if ( that.search() !== this.value ) {
                            that
                                .search( this.value )
                                .draw();
                        }
                    } );
                });*/

                /* Option 2 */
                table.columns().eq(0).each(function (colIdx) {
                    $('input', table.column(colIdx).footer()).on('keyup change', function () {
                        table
                            .column (colIdx)
                            .search (this.value)
                            .draw ();
                    });
                });             

            }
        });

Answers

  • jr42.gordonjr42.gordon Posts: 305Questions: 2Answers: 49
    edited June 2016

    The DataTable may not be completely initialized by the time your applyColumnFilter() is called. I would suggest adding that function call into initComplete first and let us know the result.

  • deveshmishradeveshmishra Posts: 6Questions: 1Answers: 0
    edited June 2016

    I am unable to call applyColumnFilter() inside initComplete, because applyColumnFilter() need reference of table which I am getting as undefined inside initComplete method.

    Can you please tell me how to get reference of table inside initComplete so that I can pass it to applyColumnFilter() method ? But still I am not sure will it work or not.

    Anyway, I have made some change in my code and it's working. What I found that there are some issues with column index earlier. Please look into the modified code.

    function applyColumnFilter() {
        // Column Level Filter on footer
        var footer = "<tfoot><tr>";
        $('#example thead th').each( function () {
            var title = $(this).text();
            columnArr.push(title);
            footer+= "<th rowspan='1' colspan='1'>" + title + "</th>";
        });
        footer+= "</tr></tfoot>";
        $('#example').append(footer);
    
        $('#example tfoot th').each( function () {
            var title = $(this).text();
            $(this).html( '<input type="text" class="searchCls" placeholder="Search '+title+'" />' );
        });
    
        table.columns().eq(0).each(function (colIdx) {
            $('input', table.column(colIdx).footer()).on('keyup change', addFooterListner);
        });
    };
    
    function addFooterListner(event) {
        console.log(event.currentTarget.placeholder);
        if(event.currentTarget.placeholder != "") {
            var index = getColumnIndex(event.currentTarget.placeholder);
            table
                .column(index)
                .search(this.value)
                .draw();
        }
    };
    
    function getColumnIndex(name) {
        // columnArr - holds all the name of columns in array
        var colname = name.split(' ')[1];
        for(var i = 0; i < columnArr.length; i++) {
            if(columnArr[i] === colname) {
                return i;
            }
        }
        return 0;
    };
    

    It's working fine. But there is one issue. My listener method is getting called n number of times, where n is the total number of columns on each keyup event. Please let me know how to get rid of this issue.

  • jr42.gordonjr42.gordon Posts: 305Questions: 2Answers: 49

    Inside initComplete, "this.api()" is your table reference. The tfoot should already be in the HTML makeup.

    See working example

  • deveshmishradeveshmishra Posts: 6Questions: 1Answers: 0

    Hi,

    The example which you have shared, is for static data. It's working for me also, even without initComplete. I am getting issue if i am providing dynamic data to datatable.

    I tried with initComplete also, but still it's not working. I called applyColumnFilter() inside initComplete and passed the table reference to it. But still it's not working as expected.

  • jr42.gordonjr42.gordon Posts: 305Questions: 2Answers: 49

    How are you getting the data to apply to DataTables? You mention "dynamic data".

  • deveshmishradeveshmishra Posts: 6Questions: 1Answers: 0

    I am reading a JSON file and preparing data from that and assigning data to DataTables.

    $(document).ready(function() {
        table = $('#example').DataTable({
            data: tableData, // Array of rows
            columns: getColumnName() // Return array of columns
        });
    });
    

    I am added so many features using DataTable Api's apart from default one. Every thing is working fine. I am getting issue only with column level filter.

  • jr42.gordonjr42.gordon Posts: 305Questions: 2Answers: 49

    Okay so my original statement still applies, you need to have tfoot element declared in the table HTML.

    Also, since this is "dynamic data" will it change? If so, how are you handling that?

    Sorry for late response.

  • deveshmishradeveshmishra Posts: 6Questions: 1Answers: 0

    As per above code, i am adding tfoot by running for loop into table. Because after assigning dynamic data, when i check by table into Google Chrome developer tool, it doesn't shows tfoot into table. That's why i am adding it manually later on.

    On dynamic data, basically i have two array which i am populating from JSON file. One array is of Row data and another is for column details in the exactly same form as it is in case of static data.

    Many thanks for your replies :smile:

  • deveshmishradeveshmishra Posts: 6Questions: 1Answers: 0

    Hey, it's working for me. I found issues in my code while adding footer element in table. Here is the update code.

    function applyColumnFilter(table, tableID) {
        var inputTxtClass = "searchCls_" +tableID; 
        $('#'+tableID).append(appendFooter(tableID, inputTxtClass));
        $("."+inputTxtClass).keyup(function(event) {
            if(event.currentTarget.placeholder != "") {
                var columnArr = getColumnArr(table);
                var index = getColumnIndex(event.currentTarget.placeholder, columnArr);
                table
                    .column(index)
                    .search(this.value)
                    .draw();
            }
        });
    };
    

    Thanks for your help :)

This discussion has been closed.