Richard
Richard

Reputation: 32909

Re-order table columns?

Does anyone know a way to re-order table columns, using jQuery?

I don't mean sort - I mean dynamically move entire columns left or right in a table.

I'm aware of the excellent dragtable plugin, but I don't need something that allows the user to move columns, I need something that will do the re-ordering in a configurable way.

Upvotes: 12

Views: 20133

Answers (4)

Phillip Senn
Phillip Senn

Reputation: 47615

I combined it with jQueryUI to get some great drag and drop action:

(function() {
    var local = {};
    local.containment = 'parent';
    local.revert = true;
    $('body thead th').draggable(local);
    $('body thead th').droppable({
        drop: dropZone
    });
    function dropZone(myEvent, myUI ) {
        var head = {};

        head.dragIndex = myUI.draggable.index();
        head.dropIndex = $(this).index();
        head.rows = $(this).closest('thead').find('tr');
        head.cellIndex = head.rows.find('th').length-1;
        head.rows.each(processTableHeaderRows);

        function processTableHeaderRows(index, element) {
            var row = {}

            row.tr = $(element);
            row.drag = row.tr.find('th:eq(' + head.dragIndex + ')');
            row.drop = row.tr.find('th:eq(' + head.dropIndex + ')');
            if (head.dropIndex === head.cellIndex) {
                row.drag.detach().insertAfter(row.drop);
            } else {
                row.drag.detach().insertBefore(row.drop);
            }
        }
        // Same thing here for td instead of th
        $(this).closest('table').find('tbody > tr').each(processRows);
        function processRows(index, element) {
            var row = {};

            row.tr = $(element);
            row.drag = row.tr.find('td:eq(' + head.dragIndex + ')');
            row.drop = row.tr.find('td:eq(' + head.dropIndex + ')');
            if (head.dropIndex === head.cellIndex) {
                row.drag.detach().insertAfter(row.drop);
            } else {
                row.drag.detach().insertBefore(row.drop);
            }
        }
    }
})();

Tried to get it to work in jsFiddle, but I couldn't. Works on my website though!

Upvotes: 1

Yiğit Yener
Yiğit Yener

Reputation: 5986

This code should work for you.

$("table tr").each(function () {
    $(this).find("td").eq(1).after($(this).find("td").eq(0));
});


Edit: If you assign $(this).find("td") to a variable this would give better performance. But the context was down to a single tr. So i assumed it would be enough just to give the idea.

$("table tr").each(function () {
    var rows = $(this).find("td");
    rows.eq(1).after(rows.eq(0));
});

Upvotes: 5

Matt Sach
Matt Sach

Reputation: 1170

Reading through the source code of the dragtable plugin, the author mentions that the algorithm for actually moving table columns was born of a discussion on the comp.lang.javascript newsgroup. That discussion is here: Swapping table columns.

In that thread, the OP is not asking about the UI side of reordering, but help with debugging a function he'd already written to swap two columns. Further down the discussion it develops into code that enables you to pass a specific column ordering, and have the code calculate all the necessary swaps/moves to get from the current ordering to the specified ordering.

It's not jQuery (most posters on c.l.js have a firm dislike of it and most other JS frameworks), and therefore it's code you can hopefully adapt for your needs and then include anywhere.

Upvotes: 2

scaryzet
scaryzet

Reputation: 923

The idea is to walk over all rows (tr's) of the table and swap the desired td's. Let's swap column 2 and column 4:

$('table tr').each(function() {
    var tr = $(this);
    var td1 = tr.find('td:eq(1)'); // indices are zero-based here
    var td2 = tr.find('td:eq(3)');
    td1.detach().insertAfter(td2);
});

I hope this helps.

Upvotes: 14

Related Questions