Search code examples
jqueryajaxjquery-uilive

jQuery live draggable / live droppable?


Basically there are two tables: Companies and visitors. Currently it's possible to drag visitors to companies. Works great. As soon as the drop function occurs, there are two $.post's. The first one saves the drag to the database. The second one updates the visitors, because the information constantly changes. The problem, however is that as soon as the second $.post finishes, Firebug keeps popping the following error:

d(this).data("draggable") is null

Which occurs in the jQuery UI file. On line 56.

about 400 times or so. So basically I'm looking for a way to do live() with draggable and droppable.

The .draggables are in #visitors (an ul). The droppables are in #companies (a table).

Thanks!

$(".draggable").draggable({
    revert:true
});
$(".droppable").droppable({
    drop: function(ev, ui) {
        $(this).text($(ui.draggable).text());

        $.post('planning/save_visit', {user_id: $(ui.draggable).attr('id'), company_id: $(this).attr('id'), period: $('ul.periods li.active').attr('id')});

        $.post('planning/' + $('ul.periods li.active').attr('id'), {visitors:true}, function(data){
            $('#visitors').html(data);
        });
    },
    hoverClass: 'drophover'
});

Solution

  • When reloading the visitors you are replacing all the draggable elements when you do $('#visitors').html(data); - so those there were draggable before are deleted and replaced with new elements that are not draggable. (I'm pretty sure you realise this, because of mentioning .live(), so this is really just here for completeness)

    However, you know exactly when the visitor elements are changed, so instead of an alternative to .live() why not just make another request for the draggable effect immediately after the change. Might be safer to "destroy" the old draggables before you replace them, but I'm not sure if that's strictly necessary.

    $.post('planning/' + $('ul.periods li.active').attr('id'), {visitors:true}, function(data){      
        $(".draggable").draggable("destroy");
        $('#visitors').html(data); 
        $(".draggable").draggable({ revert:true }); 
    });