user66875
user66875

Reputation: 2608

UI.Sortable: Default position/index when receiving a UI.Draggable

Description:

I have two Infragistics DataGrids, one is UI.Sortable and accepts rows from the second Grid which is UI.Draggable.

I use the receive Event to get the dropped, new rows position/index inside of the grid to perform a server-request to re-order the rows in the database accordingly.

It all works great, as long as I drop rows between the existing rows in the first grid. When I drop a row further down in the grid (the grid itself consists of multiple HTML table elements and a containing div tag), the row is dropped to the end of the grid (which is the desired behaviour), but the index/position that I get is always '1'.

Code:

var newItem; 
$("#tbl2 tr").draggable({
    connectToSortable: "#tbl",
    helper: 'clone'
});

$("#tbl").sortable({
    revert: true,             
    items: "tr",

    beforeStop: function (event, ui) {
        newItem = ui.item;
    },            
    receive: function (event, ui) {

        $newOrder = $(newItem).parent().children().index(newItem);
        alert($newOrder);
     }
}).disableSelection();
<div id="tbl">
    <table id="dataTbl">
        <tr><td><b>Test1</b></tr>
        <tr><td>1</td></tr>
        <tr><td>2</td></tr>
        <tr><td>3</td></tr>
        <tr><td>4</td></tr>
    </table>
</div>
<table id="tbl2">
    <tr><td><b>Test1</b></td></tr>
    <tr><td>1</td></tr>
    <tr><td>2</td></tr>
    <tr><td>3</td></tr>
    <tr><td>4</td></tr>
</table>

Demo (Simplified, I use tables instead of WebDataGrid and put a div around the first table to reproduce the same behaviour)

http://jsfiddle.net/4gLxH/10/

Upvotes: 3

Views: 604

Answers (2)

T J
T J

Reputation: 43156

As nikoshr pointed out, your sortable is the container div#tbl, not the table inside it. Hence the item will be appended to the div#tbl.

His answer is a possible workaround. However, if you actually want the container div#tbl to be the sortable, append the dropped items to the table in it and retrieve the index based on the table as in your current setup, you can update your receive handler as follows:

function (event, ui) {
   if(!$(newItem).parent().is('tbody')) // check whether it's a drop in container or not
        $(this).children('#dataTbl').append(newItem.remove()); //it so manually append the item to table
   $newOrder = $(newItem).parent().children().index(newItem);
   alert($newOrder);
 }

Demo

Upvotes: 1

nikoshr
nikoshr

Reputation: 33344

Your sortable, #tbl, is not a table, but a div containing the actual table. This means that, in certain conditions, the dragged rows can be dropped outside of the table and $(newItem).parent().children() are the children of the container, not the rows.

A simple fix would be to use your table as the sortable, something like this

var $receiver = $("#tbl").find('table');

$receiver.sortable({
    // ...
}).disableSelection();

and connect the draggables to this table :

$("#tbl2 tr").draggable({
    connectToSortable: $receiver,
    helper: 'clone'
});

See http://jsfiddle.net/dn7Z4/ for a demo.

Upvotes: 1

Related Questions