replace position of DOM element and preserve its events
-
19-04-2021 - |
Question
I am writing a jquery plugin that gets a table and allow to change the columns order.
The code for putting the column that in position oldIndex in position newIndex is:
table.find('> thead > tr, > tbody > tr').each(function() {
var row = $(this);
var children = row.children();
var source = $(children[oldIndex ]);
var destination = $(children[newIndex ]);
if (oldIndex != newIndex ) {
destination
.replaceWith(source)
.appendTo(row);
}
});
The problem is that each td has events that came outside this code. When using replaceWith
, it removes those events.
Any idea hoe can I replace position of DOM element and preserve its events?
Solution
Make sure that the bound functions are attached to the to-be-moved element.
Instead of using replaceWith
, I suggest to use logic to swap the columns. .eq
is used to select the index of a specific column, .after()
and .before()
are used to swap the columns:
Demo: http://jsfiddle.net/SfwXg/
// Indexes are zero-based
var oldIndex = 1; // = Second column
var newIndex = 2; // = Third column
var table = $('table');
if (oldIndex != newIndex) {
if (oldIndex > newIndex) {
// Let newIndex always be higher than oldIndex
var tmp = oldIndex;
oldIndex = newIndex;
newIndex = oldIndex;
}
table.find('> thead > tr, > tbody > tr').each(function() {
//or:table.children('thead,tbody').children().each(function() {
var row = $(this);
var children = row.children();
var right = children.eq(newIndex);
var left = children.eq(oldIndex);
children.eq(newIndex).after(left);
if (newIndex != oldIndex+1) {
// If they're next to each other, don't swap the columns
children.eq(oldIndex+1).before(right);
}
});
}
OTHER TIPS
How about:
if (oldIndex != newIndex ) {
var tmp = $('<td>').insertBefore(destination); // create tmp td before destination
source.after(destination); // move destination after source
tmp.after(source).remove(); // move source after tmp, remove tmp
}
EDIT: the code above swaps 2 td
s, which is different that what was asked (move a single td
).
Regardless of the problem with events, if you want to move source
before destination
, simply do source.insertBefore(destination)
, or destination.before(source)
. In your code you're moving destination
to the end of the tr
.