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?

Was it helpful?

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 tds, 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top