Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery Sortable set item to an index programmatically

I have a JQuery sortable (1.7.1 can change if necessary) list like so:

<ul id='pl'>
  <li class='item'>1</li>
  <li class='item locked'>2</li>
  <li class='item'>3</li>
  <li class='item'>4</li>
  <li class='item'>5</li>
</ul>

The second item is locked so if item 5 is tried to be moved in slot 2 it will go in slot 3 instead and if tried to be moved in slot 1 then existing item in slot 1 drops to 3 and item 5 goes to 1.

The implementation logic is easy but what I need to know is if there is any programmatic way of moving items around that would include the animations.

Did find this one already Moving an item programmatically with jQuery sortable while still triggering events but not sure if the 'sortupdate' event would simulate a drag and drop or if it would even work?

like image 325
haknick Avatar asked Feb 07 '11 23:02

haknick


2 Answers

This worked perfectly.

Follow the steps and include this:

    $el.fadeOut(1000, function(){
        $el.insertAfter($el.next());

        $el.fadeIn(1000);
    });

Like this (setting the id of the li tag of course):

jQuery(".templateMoveUp").on("click", function(){   
    $el = jQuery("#" + $(this).attr("id") + "_logTemplate");
    $el.fadeOut(1000, function(){
        $el.insertBefore($el.prev());
        $el.fadeIn(1000);
    });
});
jQuery(".templateMoveDown").on("click", function(){ 
    $el = jQuery("#" + $(this).attr("id") + "_logTemplate");
    $el.fadeOut(1000, function(){
        $el.insertAfter($el.next());
        $el.fadeIn(1000);
    });
});
like image 162
Pico Avatar answered Oct 02 '22 21:10

Pico


After a quick look on jQuery's Sortable source code it doesn't seem that such functionality is built in at this point (would be a good addition to it I'd think). Anyhow, a quick workaround I used for now in case anyone ever has the same issue:

        $el.fadeOut(1000, function(){
            $el.insertAfter($el.next());

            $el.fadeIn(1000);
        });

It somewhat clearly indicates an item moving from one spot to another.

Here's the complete code to the above problem if anyone comes around to the exact same issue.

1- Register these 2 events in the Sortable init like so:

start: function(event,ui){$(ui.item).data('initialPos', $(ui.item).offset().top)},
handle: ".drag",
stop: lockedRearrange,

2-

var lockedRearrange = function(event, ui){

    //block ordering while the current item is rearranged
    $('.drag', event.target).removeClass('drag').addClass('blockdrag');

    var $el = $(ui.item);
    var directionUp = (ui.absolutePosition.top < $el.data('initialPos')) ? true : false ;

    _rearrange($el, directionUp, $el.data('initialPos'));
};

var _rearrange = function($el, directionUp, initialPos){
    if ($el.offset().top == initialPos) {
        $('.blockdrag', $el.parent()).removeClass('blockdrag').addClass('drag');
        return;
    }

    var $knockEl = (directionUp) ? $el.next() : $el.prev();

    if ($knockEl.hasClass('locked')) {
        $el.fadeOut(1000, function(){
            (directionUp) ? $el.insertAfter($knockEl) : $el.insertBefore($knockEl);

            $el.fadeIn(1000, function(){
                _rearrange($el, directionUp, initialPos);
            });
        });
    }else
        _rearrange($knockEl, directionUp, initialPos);
};
like image 22
haknick Avatar answered Oct 02 '22 22:10

haknick