How to have sorting and filtering together in table head?

How to have sorting and filtering together in table head?

HugoHaHugoHa Posts: 6Questions: 2Answers: 0

Hello,

https://datatables.net/examples/api/multi_filter_select.html shows how to implement filtering of columns using select inputs (dropdowns). How can this functionality be placed not in the footer, but in the head of the table in an additional line (= table row) below the table head that contains the column names and the sort controls?

Thank you for a helpful hint!
HugoHa

Link to test case: https://datatables.net/examples/api/multi_filter_select.html
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:

Answers

  • kthorngrenkthorngren Posts: 22,439Questions: 26Answers: 5,161
    Answer ✓

    See this example:
    https://live.datatables.net/saqozowe/2131/edit

    It uses the second header for the search inputs and orderCellsTop to set the column sorting events in the top header. You can find other threads with more examples.

    A better optino might be to use the ColumnControl extension.

    Kevin

  • HugoHaHugoHa Posts: 6Questions: 2Answers: 0
    edited March 25

    Thank you Kevin, this works as expected! And I will take a look at the ColumnControl extension, that looks really mighty!

    The only detail left is that I have some columns without select inputs (dropdowns):

    this.api().columns([2, 3, 4, 5]).every( function () {

    The other columns (0 + 1) show the sort arrows which is not desired - how can I get rid of them? Another thing that is not completely as desired is the fact that the cells with the select inputs (dropdowns), eg in the second TR, are sensitive to clicking too and initiate sorting:

    How can this be achieved? Thank you for another helpful advice!

  • allanallan Posts: 65,653Questions: 1Answers: 10,919 Site admin
    edited April 2

    columns.orderable can be used to disable ordering for specific columns (and thus will remove the ordering icons). You can use ordering.handler to disable the default click to order as well (although that is global, not column specific).

    As Kevin says - use ColumnControl. You can readily have a search input and a sort click icon, or any combination of them. Check out this example for instance.

    Allan

  • kthorngrenkthorngren Posts: 22,439Questions: 26Answers: 5,161
    Answer ✓

    The other columns (0 + 1) show the sort arrows which is not desired - how can I get rid of them?

    Another option is to use orderCellsTop as I mentioned above. Updated test case:
    https://live.datatables.net/saqozowe/2640/edit

    Kevin

  • allanallan Posts: 65,653Questions: 1Answers: 10,919 Site admin
    Answer ✓

    Ah yes , sorry. If it's just that you don't want the icons and handler on the second row if the header, use orderCellsTop or titleRow.

    Allan

  • HugoHaHugoHa Posts: 6Questions: 2Answers: 0

    Thank you for your help - I'm really excited about how powerful this tool is and how helpful the community is!

  • HugoHaHugoHa Posts: 6Questions: 2Answers: 0

    One more thing... I implemented a fixed header for this table like described here: https://datatables.net/extensions/fixedheader/examples/options/header_footer

    This gives the following error:

    Uncaught TypeError: can't access property "sDefaultContent", col is undefined

    Without the code for the filtering of columns using select inputs (dropdowns), everything works fine, so I suppose these 2 features are not compatible together, at least in the way I combined it:

    <script type="text/javascript">
    <!--
    new DataTable('#mytable', {
        orderCellsTop: true,
        order: [[0, 'asc']], 
        pageLength: 25,
        fixedHeader: {
            header: true,
            footer: true
        },
    
        initComplete: function () {
            this.api().columns([2, 3, 4, 5]).every( function () {
                var column = this;
                var select = $('<select><option value="">(all)</option></select>')
                    .appendTo( $("#mytable thead tr:eq(1) th").eq(column.index()).empty() )
                    .on( 'change', function () {
                        var val = $.fn.dataTable.util.escapeRegex(
                            $(this).val()
                        );
    
                        column
                            .search( val ? '^'+val+'$' : '', true, false )
                            .draw();
                    } );
    
                column.data().unique().sort().each( function ( d, j ) {
                    select.append( '<option value="'+d+'">'+d+'</option>' );
                } );
            } );
        }
    
    });
    -->
    </script>
    

    What is missing here? Thank you again for a little hint!

    Best, HugoHa

  • kthorngrenkthorngren Posts: 22,439Questions: 26Answers: 5,161
    Answer ✓

    Datatables handles scrolling features like scrollX and FixedHeader by creating a duplicate header. The duplicate header is displayed and the original header is hidden. Datatables duplicates the header to facilitate scrolling. You can inspect the HTML to see this. Your code is still accessing the original hidden header.

    Use columns().header() instead. Pass in the parameter of 1 to loop through only the second row. Here is an example:
    https://live.datatables.net/ciqoguri/1/edit

    Kevin

  • HugoHaHugoHa Posts: 6Questions: 2Answers: 0

    Thank you Kevin, works perfectly now!
    Still amazed how much this community helps!

    HugoHa

  • allanallan Posts: 65,653Questions: 1Answers: 10,919 Site admin

    Yup, Kevin deserves a huge amount of kudos for the amount of help he's provided so many people over the years. Much respect :).

    Allan

  • Loren MaxwellLoren Maxwell Posts: 489Questions: 120Answers: 10

    Just lurking on this post, but I'll echo @allan in that @kthorngren's help has proven invaluable to me over the years!!

  • rf1234rf1234 Posts: 3,191Questions: 92Answers: 438

    Agree with @Loren Maxwell . Thanks a lot for your help, Kevin!

    I developed this with Kevin's help as well. Pretty similar to the above.

    This is what it looks like. The search fields also have placeholders named after the field name plus the German word for "search". I also needed to make all columns visible temporarily to make it work - and then restore the loaded state right afterwards. Fairly complicated ... I probably would have never gotten this running without Kevin's input.

    Screeenshot of some of the code:

Sign In or Register to comment.