Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to move a first td to last in a tr

I have a jqgrid, on setting multicheck I am getting the checkbox on first column, I want that checkbox column to be the last column.

I found no option on it, so I am writing a custom jquery method to move the first td of the tr to last.

I am try using

loadcomplete:function{
    var row = $(".cbox");
    for (var i = 0; i < row.length; i++) {
        var tr = $(row[i]).parent().parent().parent();
        var td = $(row[i]).parent().parent();
        var newtd = $(td).clone(true);
        $(tr).append($(newtd));
        $(tr).remove($(td)); // i am getting exception here
    }
}

Please help.

like image 544
Praveen Yenumula Avatar asked Oct 21 '11 13:10

Praveen Yenumula


2 Answers

Any reason why that's so complex? This should do it:

$('tr').each(function(){
    $('td:first',this).remove().insertAfter($('td:last',this));
});

Live example: http://jsfiddle.net/QEuxN/1/

like image 161
Jamiec Avatar answered Sep 26 '22 14:09

Jamiec


I find you question interesting, but the answer is not so easy. The problem is that jqGrid use the index of colModel column in some places to find the column value. So if one just move <td> elements inside of every row of the grid you will have correct information displayed in the grid, but the grid will be not editable. No editing mode will work with the grid.

Next problem. In the your example you used 'td:first' to get the cell with the checkbox. It will be wrong in case of usage of rownumbers: true option. In the case the checkbox will be in the second and not the first column.

The most good way to reorder the columns together with colModel will be the usage of remapColumns method like

$("#list").jqGrid('remapColumns', [0,2,3,4,...,1], true, false);

It you look at the demo which use this you will see that everything is correct at the first time, but after changing the page, sorting a column or any other refreshing of the grid the grid will be wrong filled. The reason of the problem is that the current code of jqGrid works only if the column with multiselect-checkboxes is one from the first grid columns. Look at the code fragment for example:

refreshIndex = function() {
    ...
    ni = ts.p.rownumbers===true ? 1 :0,
    gi = ts.p.multiselect ===true ? 1 :0,
    si = ts.p.subGrid===true ? 1 :0;
    ...
        idname = ts.p.colModel[ts.p.keyIndex+gi+si+ni].name;
    ...
}

The usage gi+si+ni in the index of colModel array will not work after reordering of colModel. There are other places of code inside of addXmlData, addJSONData, addRowData of grid.base.js. So to have full support of the multiselect-checkboxes one have to make changes in all the functions.

If you need only display the data in the grid without editing I can suggest you solution which looks to work good. See the demo. Before posting any code I explain you what should be done in the code.

The body of grid has always one hidden row (tr.jqgfirstrow) which will be used to set the column width. One should change the order in the columns in the row once time. Additionally one have to change the order of columns in the column headers (including the searching toolbar if it exists) and the footer (summary) row if any exist.

All other rows of the grid body should be recorded on every grid refreshing. So one should do this inside of loadComplete or gridComplete event handler. The function getColumnIndexByName

var getColumnIndexByName = function ($grid, columnName) {
        var colModel = $grid.jqGrid('getGridParam', 'colModel'), i = 0,
            cmLength = colModel.length;
        for (; i < cmLength; i += 1) {
            if (colModel[i].name === columnName) {
                return i;
            }
        }
        return -1;
    };

can be used to get the index of the column 'cb' with the checkboxes.

To move column inside of the table I used the following function

var moveTableColumn = function (rows, iCol, className) {
        var rowsCount = rows.length, iRow, row, $row;
        for (iRow = 0; iRow < rowsCount; iRow += 1) {
            row = rows[iRow];
            $row = $(row);
            if (!className || $row.hasClass(className)) {
                $row.append(row.cells[iCol]);
            }
        }
    };

which can move either all columns of all rows of the table or only the rows having specific class. The row having "jqgfirstrow" class should be moved once and other rows having "jqgrow" class should be moved on every grid refreshing. So the full code from the demo will be

var $htable, $ftable, iCheckbox, $myGrid = $("#list");

$myGrid.jqGrid({
    ... // jqGrid definition
    loadComplete: function () {
        if (typeof(iCheckbox) === "undefined") {
            iCheckbox = getColumnIndexByName($(this), 'cb');
        }
        if (iCheckbox >= 0) {
            // first we need to place checkboxes from the table body on the last place
            moveTableColumn(this.rows, iCheckbox, "jqgrow");
        }
    }
});

// if we has not local grid the iCheckbox variable can still uninitialized
if (typeof(iCheckbox) === "undefined") {
    iCheckbox = getColumnIndexByName($myGrid, 'cb');
}

// move column with chechboxes in all rows of the header tables
$htable = $($myGrid[0].grid.hDiv).find("table.ui-jqgrid-htable");
if ($htable.length > 0) {
    moveTableColumn($htable[0].rows, iCheckbox);
}

// move column with chechboxes in footer (summary)
$ftable = $($myGrid[0].grid.sDiv).find("table.ui-jqgrid-ftable");
if ($ftable.length > 0) {
    moveTableColumn($ftable[0].rows, iCheckbox);
}

// move column with chechboxes in footer in the first hidden column of grid
moveTableColumn($myGrid[0].rows, iCheckbox, "jqgfirstrow");

In the code I use some other classes and internal grid structures explained for example here. Another answer can gives additional information.

like image 31
Oleg Avatar answered Sep 24 '22 14:09

Oleg