A journey, if you will

A journey, if you will

Berserker55Berserker55 Posts: 11Questions: 5Answers: 0

This is more general feedback, hopefully it's useful to someone.

So I embarked on the task to add https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html to an already fairly advanced datatables setup.

The general idea, add a button, that when pressed, expands the header to allow column filtering like in that example. Additionally, ">30" should be a valid input to filter number columns for greater than 30 results (same for <, >=, >=).

Stumbling blocks:
No way to turn off sorting on subheaders. Due to the order of operations required, datatables would add sorting classes and sorting handlers to the filter inputs. I ended up manually adding and removing classes as well as skipping event handlers.
https://cdn.discordapp.com/attachments/860695145485303841/986868818716532787/unknown.png

If columns are hidden, the duplicate header still has them, hiding columns in the future also doesn't update the duplicate header.
https://cdn.discordapp.com/attachments/860695145485303841/986868296710225982/unknown.png

the example code is broken and throws exceptions.
https://datatables.net/forums/discussion/73093/column-filtering-example-is-broken#latest

search is terrible. I want to either apply the result of a .filter() to the table, or just be able to give .search a custom function, please. The global search.ext.push something only allows me to narrow down the result (return false -> all tables empty, return true -> default search still applies); so is entirely useless to me as I can't additionally allow the <,> filtering at all. Also it's global which is terrible in my use case.
Alternatively .hide/.show would be great too.

Here's the source code I managed to produce after a day of work and much frustration, in case that's useful to someone:
(Comparator is our class of tables with toggleable columns)

        if (!tabledata.__class__.includes("Comparator")){ // not compatible, suspect bug in datatables
            let children = tr.clone(true).addClass('filters').appendTo(thead).children("th")
            children.removeClass("sorting").addClass("sorting_disabled");
            table.columns().eq(0).each(function (colIdx) {
                // Set the header cell to contain the input element
                var cell = jtable.find('.filters > th').eq(
                    $(table.column(colIdx).header()).index()
                );
                let jcell = $(cell);
                jcell.html('<input type="text" class="form-control form-control-sm" placeholder="' + jcell.text() + '" />');
                let jinput = jcell.children("input");
                // On every keypress in this input
                jinput.on('keyup', function (e) {
                    table.column(colIdx).search(jinput.val(), false).draw()
                    })
                // prevent sorting from triggering when clicking into the input
                jinput.click(function (e) {
                    e.stopPropagation()
                })
            });
        }

Answers

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    Hi,

    Thanks for the feedback! Yes, no question we need to improve our search APIs - specifically the ability to easily apply a function to a single table (it can be done, but its discoverability is low). We've introduced SearchPanes and SearchBuilder in the last few years for end user search, but we need to improve the base APIs for developers as well (< / > filtering for example would have to be done through a function).

    Regarding the broken example - I'll reply in that thread - thanks for flagging that up.

    Allan

  • kthorngrenkthorngren Posts: 20,144Questions: 26Answers: 4,736
    edited June 2022

    If columns are hidden, the duplicate header still has them, hiding columns in the future also doesn't update the duplicate header.

    Datatables doesn't know about the inputs in the second header. You will need to keep up with your custom headers. This thread links to other threads with examples of how to keep the search header updated with column visibility.

    If this doesn't help then please provide a simple test case showing the issue so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • Berserker55Berserker55 Posts: 11Questions: 5Answers: 0

    Well, you positively suprised me that you took this as constructive criticism and proposed workarounds, will look into those soon.

  • Berserker55Berserker55 Posts: 11Questions: 5Answers: 0
            buttons.each(function (index, button) {
                var jelement = $(this);
                table.column(jelement.attr('data-column')).visible(jelement.hasClass("btn-success"));
            })
    

    I assumed table.column would also select the second header row, but it's not getting .visible toggled. Should I select it via jquery or can I get at them via datatables api in some way?

  • Berserker55Berserker55 Posts: 11Questions: 5Answers: 0

    This now works for me:

            buttons.each(function (index, button) {
                var jelement = $(this);
                // toggle second
                secondary_header.find("th").eq(jelement.attr('data-column')).toggle(jelement.hasClass("btn-success"));
                table.column(jelement.attr('data-column')).visible(jelement.hasClass("btn-success"));
            })
    

    But it does feel awkward to do it once for the second header and then the rest of the table.

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    Yes, unfortunately the API isn't very good at multi-row headers and footers. That is something I plan to address for v2. At this time the header and footer elements selects are dependent upon the orderCellsTop option, and only one will be selected from the header and footer. The workaround, is as you say, to use jQuery or DOM methods.

    Allan

Sign In or Register to comment.