Newly appended elements don't become draggable

Go To StackoverFlow.com

2

I'm creating a simple form builder to play around with jQueryUI. I have a list of form elements, just as images, which I've made draggable, set to helper 'clone'. I also have a dropable area on which I've set the drop event to read the id of the dropped image and create an appropriate form element and append it to the droppable area. Once I've appended the new element I'm then setting it to be draggable. The problem is that despite the new elements having the class ui-draggable once draggable has been called on them they aren't draggable. I want to be able to drag them around once they have been created.

Here's the code: -

var itemCount = 1;
var idToAdd;
var itemToAdd;

$(document).ready(function(){
    $(".draggable").draggable({
        opacity:0.5,
        helper: "clone"
    });

     $(".form_builder").droppable(
        {
                activeClass: "droppable_dragged",
                drop: function(e, ui){
                    var dropped_item = ui.draggable;
                    switch($(dropped_item).attr("id")){
                        case "text_box":
                            idToAdd = "textBox" + itemCount;
                            itemToAdd = "<input id='" + idToAdd + "' type='text' />";
                            break;
                        case "text_area":

                            break;
                        case "radio":
                            idToAdd = "radio" + itemCount;
                            itemToAdd = "<input id='" + idToAdd + "' type='radio' />";
                            break;
                        case "check":
                            idToAdd = "check" + itemCount;
                            itemToAdd = "<input id='" + idToAdd + "' type='check' />";
                            break;
                        case "dropdown":

                            break;
                        case "file":
                            idToAdd = "file" + itemCount;
                            itemToAdd = "<input id='" + idToAdd + "' type='file' />";
                            break;
                        case "button":
                            idToAdd = "button" + itemCount;
                            itemToAdd = "<input id='" + idToAdd + "' type='submit' />";
                            break;
                    }
                    itemCount++;
                    $(this).append(itemToAdd);
                    $("#" + idToAdd).draggable();
                }

            });
});
2012-04-04 20:27
by Carbonara
Can you setup a jsfiddle please http://jsfiddle.net - d_inevitable 2012-04-04 20:28
Your edit 3 has removed the strings that you are setting itemToAdd to - d_inevitable 2012-04-04 20:32
jsFiddle here http://jsfiddle.net/jayhouse072/7HUt2 - Carbonara 2012-04-04 20:38
Solutions here may solve your problem - Rob Hruska 2012-04-04 20:40
@d_inevitable Fixed that, not sure what happened there - Carbonara 2012-04-04 20:42


3

UPDATE The reason that it doesn't work is because the input somehow interferes with the drag event. This has nothing to do with the fact that it was dropped. I have added paddings to the element and now, dragging on the padding, it works: http://jsfiddle.net/7HUt2/4/

  1. Try to limit the scope of your variables:

    drop: function(e, ui){
       var itemToAdd;
       ...
    }
    

    This will ensure that no other simultaneous event will corrupt your program flow.

  2. Avoid seeking your objects if you can reference them directly:

    itemToAdd = '<input type="..."/>'; //No id necessary at this point.   
    $(itemToAdd).appendTo(this).draggable();
    

This will make it much more robust

2012-04-04 20:42
by d_inevitable
Ok, makes sense, thanks. I've updated the jsFiddle to append the new item like this $(itemToAdd).appendTo(this).draggable(); The only thing is though the new item still isn't draggable - Carbonara 2012-04-04 20:56
OK I found out why really isn't wokring and updated my answer with a possible hint of a workaround - d_inevitable 2012-04-04 21:20
That's great, thanks. I should have simplified my question a bit I've realised. I think people were thinking I was expecting the new elements to be draggable because of the first call to draggable and not looking at all the code as that wasn't the case. Thanks for your help - Carbonara 2012-04-04 22:49


1

Where ever you are appending the new elements you will have to apply the plugin again because the dynamically added elements do not know where to attach themselves like

 //here you add the elements with class draggable 
 $(".draggable").draggable({
      //settings here
  });
2012-04-04 20:34
by Rafay
Is that not what I'm doing by calling it after the items have been appended - Carbonara 2012-04-04 20:43
Actually jquery ui doens't need settings. And it does work if its not an input type, but a div for example: http://jsfiddle.net/7HUt2/2 - d_inevitable 2012-04-04 20:57
@d_inevitable tnx for providing the info + - Rafay 2012-04-04 21:22


0

Calling .draggable only affects existing DOM, not future DOM elements. So you need to call it again after adding in new elements you want to make draggable.

2012-04-04 20:37
by Tuan
Is that not what I'm doing right at the end of the drop event function though? I'm adding the new element to the droppable and then calling draggable on it afterwards - Carbonara 2012-04-04 20:46


0

Please try change

$('body').append(itemToAdd) 

to

$('body').append(itemToAdd).find('.draggable').draggable()

Or

$('body').append(itemToAdd);
$('.draggable').draggable(); 
2012-04-04 20:41
by allenhwkim


0

For your plugin to have effect on dynamically added elements you could use the .on() method ( .on() replaced .live() since jQuery v1.7.x ) like:

$('body').on("focusin", function(){
    $(".draggable").draggable({
        opacity:0.5,
        helper: "clone"
    });
}); // on

To sort an issue with Chrome add tabindex="1" attribute to each element with class="draggable". Other plugins had the same issue and that was the workaround.

Check this as a reference

With this workaround, you don't need to call the plugin again after adding in new elements as suggested.

2012-04-04 20:58
by JFK
Correction: It should be $('body').on() instead of $(document).on(). My bad - JFK 2012-04-04 21:13
Ads