views:

420

answers:

2

I have a script that selects and drags several elements. It works fine but when I want to add another new element to that function, append it to DOM, it does not work. The function is:

$(function() {
        var selected = $([]), offset = {top:0, left:0};
        $("#selectable1").selectable();

        $("#selectable1 span").draggable({
            start: function(ev, ui) {
                $(this).is(".ui-selected") || $(".ui-selected").removeClass("ui-selected");

                $("span").removeClass("cica"); // ads class Cica to the draged/selected element
                $(this).addClass("cica");

                selected = $(".ui-selected").each(function() {
                    var el = $(this);
                    el.data("offset", el.offset());
                    $(this).text("Selected and dragging object(s)");
                });

                offset = $(this).offset();
            },
            drag: function(ev, ui) {
                var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left;
                selected.not(this).each(function() {

                    var el = $(this), off = el.data("offset");
                    el.css({top: off.top + dt, left: off.left + dl});

                });

            },
            stop: function(ev, ui){
                $(this).text("Drag has stopped");
            }
        });
    });

The new element is added like this:

$('<span class="drag">Xia</span>').appendTo('#selectable1');

I know that I can use live to make it work but I do not know where to add it in the script. I only know how to add it on a event like click, mouseover.

Please let me know if you have some tips on this one.

Thank you

+1  A: 

What I'd do is to set up "#selectables1" with an event handler for a made-up event called "dragSetup". That would look something like this:

$('#selectables1').bind('dragSetup', function() {
  $(this).find('span:not(.dragReady)')
    .draggable({ ... })
    .addClass('dragReady');
});

Then whenever you add a new you can just call:

$('#selectables1').trigger('dragSetup');
Pointy
Pointy, I get an syntax error on this line:$(this).find('span:not(.dragReady)')iI will see if I can fix it and give it a try
Mircea
get rid of the trailing "i" - it's a typo :-) Sorry about that; I'll edit the answer.
Pointy
OK, I've done your code. It does make the new element dragable but it kills the function itself. I mean the function was meant to make the elements selectable and draggable at the same time. I probably did not implement your solution properly. I need to look more into this.
Mircea
There was a typo in #selectables1, I've just found it. This method does work. Thank you.
Mircea
+2  A: 

You have to use live to attach the events to the DOM elements that are added once the DOM is loaded. jQuery Doc for live

Teja Kantamneni
Was in the middle of typing the same answer.
RKitson
2 things - 1) You don't *have* to, but it is a better way. 2 ) That's not an accurate description of how `.live()` really works. It listens at the document level relying on the fact that events bubble, nothing is actually created or attached with new elements. The same document level listener will simply catch new element's events the same way, because they bubbled up.
Nick Craver
How is "live" supposed to work when what he's doing is using the "draggable" plugin on the elements? In other words, how is "live" going to hook up the "draggable" functionality?
Pointy
I know that live can work in my case but I do not know how to use it. I know to add it to a click on another event but in my script I can not see the actual event. Its a draggable and a selectable. I will try to find more on live.
Mircea
All you people voting this up: where's the beef? Where's an answer showing how "live()" can make "draggable()" work for dynamically-added elements?
Pointy