Unexpected behaviour of ColReorder in combination with invisible columns

Unexpected behaviour of ColReorder in combination with invisible columns

kc5151kc5151 Posts: 58Questions: 7Answers: 1

Hi,

the "column-reorder" event behaves strangely when there are columns whose visibility is set to false.

When reordering columns, the "from"/"to" attributes of the "details" variable sometimes refer to invisible column indexes and sometimes not, this even differs even when performing the same move operations several times.

Is there any way around that? I already tried initializing with

colReorder: {
  columns: ':nth-child(n+3):visible',
}

but that didn't change anything.

The reason I need the event is, that I have column specific search boxes added to my table. So I need to reliably determine which column was swapped with which column so I can swap the corresponding search boxes as well. This doesn't work though when I cannot tell which columns were actually swapped.

Thanks in advance.

«1

Replies

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    I updated a previous example I had to include colreorder.
    https://live.datatables.net/dikuduka/87/edit

    It seems to work. The search inputs follow the column to include searching. Changing the visibility of a column also works. Maybe this example will help.

    I added the column-reorder event but not sure how to recreate the issue. I hid the Position column and moved the Age column to the far left. Here is the output:

    {
        "from": [
            3
        ],
        "to": 2,
        "mapping": [
            0,
            1,
            3,
            2,
            4,
            5
        ]
    }
    
    
    {
        "from": [
            2
        ],
        "to": 0,
        "mapping": [
            1,
            2,
            0,
            3,
            4,
            5
        ]
    }
    

    The from and to seem to be correct for this move and don't reference the hidden column index of 1.

    Please update the text case or create your own to show the issues you are having so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Thanks for your help, especially with the test case.

    I've updated it and hidden 2 columns. If you move around the position column, it will now sometimes trigger an error (it will log an error if either the "from" or the "to" column is invisible):

    https://live.datatables.net/dikuduka/90/edit

    You might have to move it further to the right to trigger the problem, when only swapping the 1st and 2nd (displayed) column it doesn't always trigger. But it reliably triggers for me when moving the first column e. g. to the third column and then back to the leftmost spot (but it also triggers on other moves).

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    In your test case move Position to the right of Start Date

    Error, from is invisible
    {
        "from": [
            2
        ],
    ....
    }
    

    Click on Column Visibility and you will see the Age column is now at index 2. Looks llike you wil want ot use the column-selector of {integer}:visible index. I updated your test case with this selector:
    https://live.datatables.net/qelojuto/1/edit

    The added console output will highlight the difference of using :visIdx. Does this solve your issue?

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Thanks again, however, the visIdx is sometimes undefined:

    https://live.datatables.net/vekopisa/1/edit

    So I don't quite understand how I could rely on that.

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    Yep, that does seem to be an issue. @allan will need to take a look.

    You indicated a problem with column search inputs. I believe my example works no matter the order or visibility. Does that help you solve your issue?

    If not maybe provide a test case showing the issue you are trying to solve so we can try to offer suggestions.

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Thanks for highlighting :-). I've added column specific search input fields similar to https://datatables.net/examples/api/multi_filter.html (my actual code looks different of course, but I don't think it matters). When I now reorder the columns, the search input fields stay where they originally were placed, so e. g. the search input for column #1 now filters column #3. Or are you suggesting that this should work out of the box without "manually" swapping the search inputs? If so, I'll have to re-examine my code and the given example again.

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Ohh, my bad, I just saw that you actually have column searches in your example (didn't even notice!). I'll re-examine my code to see where I messed things up there. Thanks again!

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1
    edited September 26

    Ok, I've now created a test case that more closely resembles my setup.

    I'm using server side processing with ajax:

    https://live.datatables.net/lulevosu/1/edit

    Now, when I move the columns, the search boxes are not moved along with them.

    Instead of

    column.header().parentNode.parentNode.appendChild(row);
    

    I also tried adding:

    $('#example thead').append(row);
    

    but the results for this were actually worse; the search inputs disappeared when the site was done loading unless I disable scrollX and scrollY. And the original problem remained.

    Could you maybe have a look again and point me in the correct direction? Thanks a bunch!

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

    Sounds like the issue is resolved, however, just quickly regarding the :visIdx, if I take this line:

    console.log(
       'from-Index: ' + table.column(details.from).index() +
      '  VisIdx: ' + table.column(details.from+':visIdx').index()
    );
    

    They aren't the same thing. For example, if details.from is 1, then the two selectors would be 1 (i.e. column data index 1) and 1:visIdx (i.e. column visible index 1). They are not always the same thing.

    You can use column.index() to convert between visible and data index.

    However, I think all of that is irrelevant in this case :)

    Allan

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1
    edited September 26

    Hey Allan, you're right ofc, the original focus of this thread has shifted a bit. But my original problem still remains (see my post above yours), even though it can probably be resolved without the column-reorder event. Hope someone has time to take a look at what I messed up there :-).

    On a related note: I've updated my most recent test case (https://live.datatables.net/lulevosu/1/edit) again to show another problem: when using Bootstrap (well, I assume that's the reason at least), when dropping a column onto another column while reordering the sort order changes. This only happens when you drop the column on another column header (but most people will probably do so).

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

    Right - the problem with the search boxes not moving is that you are dynamically creating a row in the header after the DataTables initialisation. DataTables knows nothing about that new row, so it doesn't move the cells in it.

    What happens on start up is that DataTables will scan the table header and cache information about it, so it can do things like moving cells around, etc. This approach in the example sidesteps that, and I'm afraid will never work with DataTables.

    You have to setup the multi-row header before the DataTable is initialised. With that, the example will then work.

    I suspect the sort order changing is something related to that, as my multi-row header example for ColReorder doesn't show that behaviour.

    Allan

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Hi Allan. Sorry for being daft, but how could I go about that? Since I'm using Ajax / the "columns" attribute, it's Datatables that builds the initial table header.

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

    In this case you'd need to create the header before the DataTable is initialised. Very similar to what you are currently doing in initComplete for a single row, but instead of just one row, create two (one for the titles, one for the inputs). You'll probably need to create the thead as well.

    Allan

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1
    edited September 26

    Well, the problem I'm having is that I still need to use the "columns" initialization option, since I have invisible columns and stuff.

    When I manually set up a table header, I looks like I have to rename the "title" attribute from "columns", otherwise it messes things up, so I did that.

    But it also messes things up if "visible: false" is set in one of my column definitions.

    Could someone please have a look?

    https://live.datatables.net/wowizoqu/1/edit

    Note that there are several problems visible:

    I have set the "Office" column to "visible": false, but the "Salary" column is missing from the output as well. Also, the Datatable init fails; the Ajax call goes through in my actual project and there is actually data being displayed, but there are column headers missing that should be there.

    If you add a "return" statement before the Datatable is initialized, the "Salary" column shows up, so I don't know what's going on here.

    I cannot seem to use columnDef: instead of columns: since the data attribute is not passed through (and "data" is what I use to identify the SQL column in my actual project).

    Thanks again, I'm probably missing something very basic here.

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

    Don't skip the creation of the header cells just because they aren't to be visible: https://live.datatables.net/wowizoqu/3/edit . DataTables will remove them from the DOM for you on initialisation.

    What you want to do is create a thead structure that is correct for the table before the DataTable is initialised.

    Allan

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    In addition to Allan's updated example you will need to change the selector used for the keyup event. Due to scrolling there is a cloned header used to facilitate scrolling. Using the selector #example thead will find the original / hidden header. Use api table().container() instead, for example:
    https://live.datatables.net/wowizoqu/2/edit

    I worked out a different solution to create the header but Allan beat me to an example :smile:

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Thank you both so much, I was able to get it working in my project :smiley:

    Just a minor problem remains: As mentioned earlier, the column sort order changes when reordering columns. This behavior can also be seen in your examples:

    https://live.datatables.net/wowizoqu/2/edit
    https://live.datatables.net/wowizoqu/3/edit

    Is there a solution to this problem as well?

    I already experimented with e.stopPropagation() in the columns.reordered event earlier, but that didn't work.

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    See this thread for two options.

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Hi Kevin. Thanks, but there seems to be a misunderstanding. I don't want to disable ordering, I just don't want it triggered when I reorder columns.

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    Sorry, I'm not seeing the issue of the order changing when reordering the columns in either of those examples. Here is a before show:

    Moved the Salary column and the sorting did not change:

    Please provide the steps needed to replicate the issue.

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Hi Kevin. I can reproduce the behaviour in both, Chrome and Firefox (and its the same under Linux and Windows). When you drag a column to another position by dragging the first header line (i. e. the column name), its order changes. It doesn't change if you drag the second header line (i. e. the line with the search bars), presumably because of orderCellsTop: true.

    I just revalidated that with the examples given by you and Allan:

    https://live.datatables.net/wowizoqu/2/edit
    https://live.datatables.net/wowizoqu/3/edit

    Thanks for your time.

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    I'm using Chrome on a Mac and not able to reproduce the issue. Here is a video:

    https://www.loom.com/share/81440384100d4e2a859375a9d7a4eb7b?sid=4089e152-b334-4564-90dd-867237d02aac

    Maybe @allan can test with Windows or Linux.

    Are you able to reproduce with this example?

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1
    edited September 26

    The https://datatables.net/extensions/colreorder/examples/initialisation/complex-header.html example does NOT trigger the behaviour. I assume it has something to do with Bootstrap integration (I believe I mentioned that earlier in this thread), but actually I'm pretty clueless.

    Edit: unsure if it's of relevance, but when I drag the order icon next to the column title, it doesn't change sort order. It does change when I drag from somewhere else in the first header line.

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    Here is the same example with BS 5. I'm still not able to recreate the issue:
    https://live.datatables.net/wowizoqu/5/edit

    It doesn't matter which part of the cell I use to drag.

    I wonder if its your mouse where it's double clicking when not expected. Checkout this thread. Have you tried a different mouse or difference computer?

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    It's not a hardware issue, I tried this at work and at home with the same result and https://datatables.net/extensions/colreorder/examples/initialisation/complex-header.html does NOT trigger the problem. https://live.datatables.net/wowizoqu/5/edit DOES trigger the probem.

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975

    Wonder if its the development mode. Try the live preview mode:
    https://live.datatables.net/wowizoqu/5

    Kevin

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    https://live.datatables.net/wowizoqu/5 also triggers the problem.

  • kc5151kc5151 Posts: 58Questions: 7Answers: 1

    Maybe somebody else can confirm that they spot the same behaviour I do or if I've started hallucinating :wink:? To get a tiny bit more technical, if I reorder columns by dragging "dt-column-title", the sort order of the column changes. If I drag "dt-column-order", it doesn't.

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

    That was useful info - thank you.

    It appears to be something to do with the scrolling options. On this example I can recreate the issue as well (click and dragging on the title).

    I'll look into that and let you know.

    Allan

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

    I've done a fair deep dive on this one and what appears to be happening is that when the mouse button is released, I remove the DOM element, then Firefox is triggering a click over the element that the mouse is now on. So it looks like a real click to sort. It does not happen in Chrome.

    I've committed a change that will put a blocking event in for just a moment, long enough to hide the "drag click" from the element and then remove it. That seems to do the job in Firefox.

    Allan

Sign In or Register to comment.