Search code examples
jquery-uijquery-ui-sortable

How to get an object of the new element, which was placed instead of previous object in jQuery UI sortable?


The source:

<ul class="supercategory">
    <li>
    <div class="supcat">
        <h4>
        <a class="new" href="/header1.html">header 1</a>
        </h4>
        <ul class="category">
            <li><a href="item1.html">Item 1</a></li>
            <li><a href="item2.html">Item 2</a></li>
        </ul>
    </div>
    </li>
    <li style="" class="">
    <div class="supcat">
        <h4>
        <a class="new" href="/header2.html">Header 2</a>
        </h4>
        <ul class="category">
            <li><a href="item1.html">Item 1</a></li>
            <li><a href="item2.html">Item 2</a></li>
        </ul>
    </div>
    </li>
</ul>
<div id="test">
</div>

a lit bit of css:

ul.supercategory { background: lightblue; }
.new{ background: yellow; }

and a jQuery UI force:

$('.supercategory').sortable({
            cursor: 'move',
            axis: 'y',
            revert: true,
            stop: function (event, ui) {  }
        });

I know that to get an object of the current dragged element I simply must to make something this:

stop: function(event, ui) { var obj = ui.item; }

But how to get an object of placed element instead of I dragged to new position?

For example, if I dragged first li on the new position (it will 2nd li) the second li was placed on the place instead of my, how to get this element as object in jQuery UI sortable?

Watch my fiddle: http://jsfiddle.net/Stasonix/jCMuQ/1/

upd 1. First of all a fiddle. http://jsfiddle.net/Stasonix/jCMuQ/5/

Than code:

var is_received = false;

$('.supercategory').sortable({
            cursor: 'move',
            axis: 'y',
            revert: true,
            receive: function(event, ui){ is_received = true;  },
            stop: function (event, ui) {

                is_received = true;

            },

    deactivate: function(event, ui) {

        if (is_received){

            $('#test').text(ui.item.find('.new').attr('href'));

            is_received=false;

        }            

    }


 });

Well... still need a solution, it's not works seems.


Solution

  • You can try this to get the new object you dragged by keeping track of your object's index / position, and by using the events start and deactivate like this:

    // Define static variables to keep track of the index / position of your dragged object
    var prev_index =  null;   // Previous index / position of your dragged object
    var next_index = null;    // Next index / position of your dragged object
    
    $('.supercategory').sortable({
        cursor: 'move',
        axis: 'y',
        revert: true,
        start : function(event, ui) {
            prev_pos = ui.item.index();
        },
        deactivate : function(event, ui) {
            next_pos = ui.item.index();
        },
        stop : function(event, ui) {
            // Your new object: "el"
            var el = null;
    
            if(next_pos > prev_pos)
                el = $(".mydrag").get(next_pos-1); // Your previous object has been dragged! Your previous object was initially above your new object (Dragging downward)
            else if(next_pos<prev_pos)
                el = $(".mydrag").get(next_pos+1); // Your previous object has been dragged!  Your previous object was initially below your new object (Dragging upward)
            else
                el = $(".mydrag").get(prev_pos);   // Your previous object was not dragged and is at the same position
    
            $('#test').text($(el).find('.new').attr('href'));
        }
    });
    

    The thing is,

    • if your object was dragged successfully, depending on whether you drag your object downward or upward, the new object you're looking for will be located above or below the dragged object, so: at the new index / position of your dragged object -1 / +1
    • however, if your object was not dragged successfully, there is "no new object", so your new object is your dragged object.

    Make sure to add the class .mydrag to your draggable li elements:

    <ul class="supercategory">
        <li class="mydrag">
            <div class="supcat">
                <h4>
                    <a class="new" href="/header1.html">header 1</a>
                </h4>
                <ul class="category">
                    <li><a href="item1.html">Item 1</a></li>
                    <li><a href="item2.html">Item 2</a></li>
                </ul>
            </div>
        </li>
        <li class="mydrag">
            <div class="supcat">
                <h4>
                    <a class="new" href="/header2.html">Header 2</a>
                </h4>
                <ul class="category">
                     <li><a href="item1.html">Item 1</a></li>
                     <li><a href="item2.html">Item 2</a></li>
                 </ul>
            </div>
        </li>
    </ul>
    <div id="test">
    </div>
    

    I'm not sure if this solution is what you were exactly looking for... You can ask me question if I was not clear.