Unexpected behaviour of ColReorder in combination with invisible columns
Unexpected behaviour of ColReorder in combination with invisible columns
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.
Replies
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: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
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).
In your test case move Position to the right of Start Date
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
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.
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
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.
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!
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
I also tried adding:
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!
Sounds like the issue is resolved, however, just quickly regarding the
:visIdx
, if I take this line:They aren't the same thing. For example, if
details.from
is 1, then the two selectors would be1
(i.e. column data index 1) and1: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
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).
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
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.
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 thethead
as well.Allan
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.
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
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. Useapi 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
Kevin
Thank you both so much, I was able to get it working in my project
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.
See this thread for two options.
Kevin
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.
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
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.
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
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.
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
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.
Wonder if its the development mode. Try the live preview mode:
https://live.datatables.net/wowizoqu/5
Kevin
https://live.datatables.net/wowizoqu/5 also triggers the problem.
Maybe somebody else can confirm that they spot the same behaviour I do or if I've started hallucinating ? 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.
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
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