how to trigger JQuery .draggable() on elements created by templates?

meteor

Solution

EDIT: This approach doesn't seem to work in the latest versions of Meteor, e.g. v0.5.0. See my comment below.

Looks like we're working on similar things! I've got a working proof of concept for a simple Magic: The Gathering app. Here's how I have dragging implemented at the moment:

In a `<head>` section in one of your html files, include the jQuery UI script:

<script src="jquery-ui-1.8.20.custom.min.js"></script>

Then, in a js file, make sure elements become draggable on mouseover (note: this is sub-optimal on touchscreens since it requires two touches to drag... I'm looking for a better touchscreen solution):

Template.card_item.events['mouseover .card, touchstart .card'] = function (e) {
    var $target = $(e.target);
    if (!$target.data('isDraggable')) {
      $target.data('isDraggable', true).draggable();
    }
};

And finally, handle the `drag` and `dragstop` events:

var prevDraggedTime = 0

Template.card_item.events['drag .card'] = function (e) {
    // get the cardId from e
    var now = new Date().getTime();
    var position;

    if (now - prevDraggedTime > 250) {
        position = $(e.target).position();
        Cards.update(cardId, {$set: {x: position.top, y: position.left}});
        prevDraggedTime = now;
    }
}

Template.card_item.events['dragstop .card'] = function (e) {
    // get the cardId from e
    var position = $(e.target).position();
    Cards.update(cardId, {$set: {x: position.top, y: position.left}});
}

Problem

I have a standard template in an Html file like: ``` <template name="cards"> {{#each all_cards}} {{> card_item}} {{/each}} </template> <template name="card_item"> <div class="card" style="left:{{position.x}}px; top:{{position.y}}px"> {{title}} </div> </template> ``` I want to have the cards (css selector .card) become draggable with JQuery. Now since Meteor automagically updates the DOM using the template, when and how do I know where to call .draggable() on what?? EDIT: This is so far my solution which makes pending movements on other client visible with a wobble animation (using CSS3): ``` Template.card_item.events = { 'mouseover .card': function (e) { var $target = $(e.target); var $cardContainer = $target.hasClass('card') ? $target : $target.parents('.card'); $cardContainer.draggable({containment: "parent", distance: 3}); }, 'dragstart .card': function (e) { Session.set("dragging_id", e.target.id); $(e.target).addClass("drag"); pos = $(e.target).position(); Events.insert({type: "dragstart", id:e.target.id, left: pos.left, top: pos.top}); }, 'dragstop .card': function (e) { pos = $(e.target).position(); Events.insert({type: "dragstop", id:e.target.id, left: pos.left, top: pos.top}); Cards.update(e.target.id, {$set: {left:pos.left, top:pos.top}}); Session.set("dragging_id", null); } } Events.find().observe({ added: function(event) { if (event.type == "dragstart" && !Session.equals("dragging_id", event.id)) { $("#"+event.id).draggable({disabled: true}); $("#"+event.id).addClass("wobble"); } if (event.type == "dragstop" && !Session.equals("dragging_id", event.id)) { $("#"+event.id).animate({left: event.left, top: event.top}, 250); Events.remove({id:this.id}); $("#"+event.id).draggable({disabled: false}); } } }); ```

Original source

Related problems