columns(':visible') return invisible columns

columns(':visible') return invisible columns

sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
edited May 22 in Free community support

$0.dataTable.columns(':visible').visible().toArray()
(4) [true, true, false, true]

Any idea how it is possible that :visible returns invisible columns?

We use datatables 2.0.7.
I cannot yet reproduce it isolated: https://jsfiddle.net/vb8rm5s0/4/ (click on button)

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    Not immediately sure I'm afraid. I'd need a test case that shows the error.

    Allan

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 22

    I took a look at the code. While I understand only a quarter of it, I was surprised, that the regexp __re_column_selector (/^([^:]+):(name|title|visIdx|visible)$/) does not match on the selector :visible. It would match only when removing the prefix ([^:]+) to have the regexp /^:(name|title|visIdx|visible)$/. Is that as intended?

    Surprisingly this regexp has no effect in the above jsfiddle, anyway: The columns seem to be filtered correctly. Possibly because the jquery node-based selection in 8311 of datatables.mjs kicks in:

            // jQuery selector on the TH elements for the columns
            var jqResult = $( nodes )
                .filter( s )
                .map( function () {
                    return _fnColumnsFromHeader( this ); // `nodes` is column index complete and in order
                } )
                .toArray();
    

    Edit: I see now that the regexp is fine and intended for prefixed selectors.

        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * Columns
         *
         * {integer}           - column index (>=0 count from left, <0 count from right)
         * "{integer}:visIdx"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)
         * "{integer}:visible" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)
         * "{string}:name"     - column name
         * "{string}"          - jQuery selector on column header nodes
         *
         */
        
        // can be an array of these items, comma separated list, or an array of comma
        // separated lists
        
        var __re_column_selector = /^([^:]+):(name|title|visIdx|visible)$/;
    
  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 22

    I am a step further (please intervene, when you see something): The difference is that in my full situation I have a complex header with two rows, while in the jsfiddle I have only one row.

    When reducing the header rows two one, columns(':visible') can correctly filter.

    Would it be possible for you to manipulate my jsfiddle example to be one that:
    * has two rows of header cells
    * still has column definitions for the lowest header row

    I ask because our example is spread over multiple classes and very complex. It also is historically grown from a very old datatables version and might not fit into the todays way of setup any more, unknowingly.

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin
    Answer ✓

    Yup it is for the prefix.

    What is different between your page and the example you created? I'm wondering what would be different that it would fail locally but not in the example.

    Allan

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0

    I just noticed that the example uses jquery 1.12.0 while we use 3.7.1.
    I upgraded jsfiddle, including multi row header (how I think is correct), but still not reproducible.
    https://jsfiddle.net/vb8rm5s0/5/

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 22

    @allan I can now reproduce it:
    Example A: https://jsfiddle.net/vb8rm5s0/7/ (works: gives data of column a and c)
    Example B: https://jsfiddle.net/vb8rm5s0/8/ (failure: gives data of column a, b and c)

    In both examples we hide the second column. The difference is that in example B the first header row has defined a row-span over row 2's first and second column.

    This further leads to a error thrown in our fixed column plugin (5.0.0), because for an invisible cell you cannot get the visible index (see line 3 below, which matches actual line 156 in dataTables.fixedColumns.mjs):

                // Loop over the visible columns, setting their state
                dt.columns(':visible').every(function (colIdx) {
                    var visIdx = dt.column.index('toVisible', colIdx);
                    var offset;
                    if (visIdx < start) {
                        // Fix to the start
                        offset = that._sum(widths, visIdx);
                        that._fixColumn(visIdx, offset, 'start', headerStruct, footerStruct, barWidth);
                    }
                    else if (visIdx >= colCount - end) {
                        // Fix to the end
                        offset = that._sum(widths, colCount - visIdx - 1, true);
                        that._fixColumn(visIdx, offset, 'end', headerStruct, footerStruct, barWidth);
                    }
                    else {
                        // Release
                        that._fixColumn(visIdx, 0, 'none', headerStruct, footerStruct, barWidth);
                    }
                });
    

    What would be the correct way to fix this?
    Anything to be done on your side?

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 22

    Formed as a concrete Bug report (DT 2.0.7):

    BUG: When making a column invisible that is below a column header cell with colspan, the columns(':visible') does not adapt to the new visible state.

    Reproduction:
    1. Got to https://jsfiddle.net/abh0c13n/
    2. Click on "Give me visible data" (you see data of column a, b and c)
    3. Click on "Toggle second column's visiblity" button (second column gets invisible)
    4. Click on "Give me visible data" (you see data of column a, b and c)

    Expected:
    Step 4 should show only data of column a and c.

    Dev hints:
    column(':visible') relies on data-dt-column attribute of the <th> element and is set to 0,1 for the only header cell with colspan="2". When hinding one of it child columns the colspan attribute value is reduced to 1, but data-dt-column is not updated, resulting in the very same return value of columns(':visible') in both situations.

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0

    I accidentally marked a comment of yours as answer. Ignore that, please. Issue is still open. :)

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    Excellent work tracking that down - thank you for the instructions and test case. That is indeed an error due to the colspan. I'll look into how I can address that.

    Allan

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    Fix committed :). I aim to release a patch release of DataTables tomorrow, which will carry this fix.

    Allan

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0

    Hi Allan,
    thank you for the rapid fix! I could successfully test this fix.
    Because I can only use official versions: Any news on the release date?
    Greetings, Sebastian

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    Yes, sorry, I got bogged down in other things at the end of the week. The new plan is tomorrow (Tuesday).

    Allan

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 28

    With your fix applied locally I see another problem that has a similar signature:

    TypeError: Cannot read properties of undefined (reading 'anCells')
        at _pluck_order (dataTables.mjs:1182:1)
        at _Api.eval (dataTables.mjs:8463:1)
        at _Api.iterator (dataTables.mjs:6721:1)
        at _Api.eval (dataTables.mjs:8462:1)
        at _Api.eval (dataTables.mjs:6939:1)
        at _Api.eval [as nodes] (dataTables.mjs:6811:1)
        at FixedColumns._fixColumn (dataTables.fixedColumns.mjs:261:72)
        at _Api.eval (dataTables.fixedColumns.mjs:161:1)
        at _Api.eval (dataTables.mjs:9530:1)
        at _Api.iterator (dataTables.mjs:6721:1)
    

    We use both, latest scroller and fixed columns plugin.

    This happens when dataTable.fixedColumns.mjs does invoke dt.column(idx + ':visible', { page: 'current' }).nodes() aiming to pass the result to applyStyles function in line 261. The method is called on initial rendering without problems but occurs on the first fetch for the next page by the scroller plugin on vertical scrolling.

    I cannot give you a jsfiddle, since the previous bug does not allow reaching the point and I can't patch the 2.0.7 version in jsfiddle.

    Sebastian

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 28

    If you later exchange the version of datatables in this jsfiddle with 2.0.8, you might be able to see the issue - I can't guarantee it. So far it at least shows a different symptom of the initial bug:

    https://jsfiddle.net/fkrcym54/

    1. Open jsfiddle
    2. Click on "Toggle second column's visiblity" button

    Result:

    • Errors in Console output
    • Scroller plugin stopped working
  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0

    (Offtopic: Would be cool to be able to delete one's own posts/comments, also GDPR wise)

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    I've updated the Fiddle to use the nightly build of DataTables and it appears to work okay. Is it happy for you as well?

    Regarding deleting of comments - I had some problems in the past with people adding essential information out of sequence and not noting it, getting cross about it, pretending it didn't happen. It was very frustrating, so I reduced the editing window to about 15 minutes.

    I do need to review that now! Perhaps a delete only option if the forum software allows that. Thanks for highlighting it.

    Allan

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    Forgot to say - if you need anything deleted, just ask and I'll purge it.

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 28

    Thank you again for your quick reply.

    Is it possible to integrate your nightly in an existing npm build, the same way as the released version? To tell whether it works I need datatables loaded like a normal release using NPM (we also use types that come along with it and even patch them a bit - Faking this would take some time).

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    Is it possible to integrate your nightly in an existing npm build, the same way as the released version?

    Yes, this is the repo. See this SO post on how to use a specific hash from a git repo.

    I plan to ship 2.0.8 later today all being well.

    Allan

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    That's 2.0.8 published. I'm just updating the site.

  • sebastianbarthsebastianbarth Posts: 43Questions: 11Answers: 0
    edited May 28

    Just tested. Works wonderfully!
    Thank you Allan

  • allanallan Posts: 63,434Questions: 1Answers: 10,458 Site admin

    Awesome - thanks for letting me know.

    Allan

Sign In or Register to comment.