Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to properly bind jquery ui behaviors in meteor?

I am trying to create a group of draggable DOM objects using jQuery UI's .draggable() that are populated through Meteor subscriptions. The code I came up with looks like

Meteor.subscribe('those_absent', function() {
     $( "li.ui-draggable" ).draggable( { revert: "invalid" } );
});
Meteor.subscribe('those_present', function() {
     $( "li.ui-draggable" ).draggable( { revert: "invalid" } );
});

These correspond with some Meteor.publish() calls, so that any time the collection changes, the .draggable() behaviour will be attached. At least, that was my intention.

However, it only works once - once one of these <li>'s has been dragged and dropped, then they are no longer draggable at all.

When the objects are dropped, I'm firing a custom event that is attached to the Template for the item like so

    $( "#c_absent .inner-drop" ).droppable({
        drop: function( event, ui ) {
            ui.draggable.trigger('inout.leave');
        }
    });


  Template.loftie_detail.events = {
      'inout.leave': function (e) {
          Lofties.update({_id:this._id}, {$set: {present: 'N' }});
      }
  };

So, my thinking is that this change to the collection on drop should propagate through the pub/sub process and re-run the .draggable() line above. But it doesn't seem to.

The complete code for this can be seen here https://github.com/sbeam/in-out/blob/master/client/inout.js and the app is live at http://inout.meteor.com/ (there are some other probably unrelated issues with items randomly losing values or disappearing from the UI altogether)

So if my understanding of how pub/sub works in Meteor is off, it would be good to know. Or is there a more efficient way to achieve this UI behavior binding that works without it?

like image 745
sbeam Avatar asked May 16 '12 12:05

sbeam


1 Answers

The way I have implemented this in my apps is with the method shown by @lashleigh.

I have a template event that listens using code like this :

Template.myDraggableItem.events({
    'mouseover .workItem' : function() {
        $(this._id).draggable();
    }
});

Then I listen for the dragstop like this.

$('body').on('dragstop', '.myDraggableItem', function (e) {
    // Update the collection with the new position
};

You can see the app that's using this code at aduno.meteor.com

like image 129
Braden Avatar answered Oct 18 '22 16:10

Braden