How do you add a filter to the header only using the API?

How do you add a filter to the header only using the API?

mwanderson71mwanderson71 Posts: 2Questions: 2Answers: 0

I am struggling to understand how to add a filter to each column. To set things up, I never add any header or footer HTML code into the .cshtml since datatables really doesn't need it. This keeps the page cleaner and I am looking for a way to continue down this path.

What I want to be able to do is to use something like the columns property and have it create the filter header for me. If you look at the columns properties that I am using below, you can see that I can tell it what data to pull from the json and what the title of the column should be. I have to imagine that there is another property that I am just not seeing or understanding that will allow the filter to show up over the column?

What I am hoping to be able to do is to say something like this:

{ data: "InvoiceDate", title: "Invoice Date", filter: true }

Here is my code snippet:

var table = $('#example').DataTable({
                dom: "<'dt-toolbar'<'col-xs-12 col-sm-6'f><'col-sm-6 col-xs-6 hidden-xs'lB>>" +
                    "t" +
                    "<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-sm-6 col-xs-12'p>>",
                buttons: ['copy', 'excel', 'pdf', 'print'],
                responsive: true,
                processing: true,
                serverSide: true,
                paging: true,
                pageLength: 25,
                lengthMenu: [[10,25,50,100,-1], [10,25,50,100,"All"]],
                ajax: {
                    type: "POST",
                    url: 'BillingDataHandler'
                },
                columns: [
                    {
                        "class": 'details-control',
                        orderable: false,
                        data: null,
                        title: '',
                        defaultContent: ''
                    },
                    { data: "InvoiceDate", title: "Invoice Date" },
                    { data: "InvoiceNumber", title: "Invoice Number" },
                    { data: "DispatchId", title: "Dispatch Id" },
                    { data: "CustomerName", title: "Customer Name" },
                    { data: "GrossAmount", title: "Gross Amount" },
                    { data: "VoucherAmount", title: "Voucher Amount" },
                    { data: "Verified", title: "Verified" },
                    { data: "VerifiedBy", title: "Verified By" }
                    
                ]
            });

Thanks for any and all help!

Answers

  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin

    Yup - I see what you are looking for, and this is something I hope to introduce in future, but there isn't a way to do that at the moment. The column properties don't have a public API yet, so you would need to get the filter property via the private properties - which is not recommended.

    Instead, what you could do is use columns.className to set a suitable class name (e.g. filter) and then select the columns with that class name and build the column filter for them.

    Allan

  • HPBHPB Posts: 73Questions: 2Answers: 18

    Like @allan suggested, this can be tackled with column classnames.

    My solution was to add search_text className to the columns I want filtering on and add below as my initComplete

    initComplete: function (settings, json) {
            var table = this.api();
            // Setup - Replace th with search_text class with input boxes
            table.columns('.search_text').every(function () {
                var column = this;
                var header = $(column.header()).html();
                var input = $('<input type="text" style="height:26px;"/>')
                    .appendTo($(column.header())
                    .empty()
                    .append('<div>' + header + '</div>'));
                //Restoring state
                input.val(column.search());
                input.on('keyup', function (e) {
                    //Ignore keys without value (like shift/ctrl/alt etc) to prevent extensive redraws
                    var ignore = [9, 13, 16, 17, 18, 19, 20, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 91, 92, 112, 113, 114, 115, 116, 117, , 118, 119, 120, 121, 122, 123, 144, 145];
                    if (ignore.indexOf(e.which) != -1)
                        return;
                    table.column($(this).parent().index() + ':visible').search(this.value).draw();
                });
                //Prevent enter key from sorting column
                input.on('keypress', function (e) {
                    if (e.which == 13) {
                        e.preventDefault();
                        return false;
                    }
                });
                //Prevent click from sorting column
                input.on('click', function (e) {
                    e.stopPropagation();
                });
                // There are 2 events fired on input element when clicking on the clear button:// mousedown and mouseup.
                input.on('mouseup', function (e) {
                    var that = this;
                    var oldValue = this.value;
                    if (oldValue === '')
                        return;
                    // When this event is fired after clicking on the clear button // the value is not cleared yet. We have to wait for it.
                    setTimeout(function () {
                        var newValue = that.value;
                        if (newValue === '') {
                            table.column($(that).parent().index() + ':visible').search(newValue).draw();
                            e.preventDefault();
                        }
                    }, 1);
                });
                //Make nodes tabbable withtout selecting td
                input.parent().attr('tabindex', -1);
            });
    }
    
  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin

    Perfect! Thanks for sharing your code with us.

    Allan

This discussion has been closed.