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();
                }

            });
});
Carbonara
  • 69
  • 2
  • 9

5 Answers5

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

d_inevitable
  • 4,381
  • 2
  • 29
  • 48
  • 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 Apr 04 '12 at 20:56
  • OK I found out why really isn't wokring and updated my answer with a possible hint of a workaround. – d_inevitable Apr 04 '12 at 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 Apr 04 '12 at 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
  });
Rafay
  • 30,950
  • 5
  • 68
  • 101
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.

Tuan
  • 5,382
  • 1
  • 22
  • 17
  • 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 Apr 04 '12 at 20:46
0

Please try change

$('body').append(itemToAdd) 

to

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

Or

$('body').append(itemToAdd);
$('.draggable').draggable(); 
allenhwkim
  • 27,270
  • 18
  • 89
  • 122
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.

Community
  • 1
  • 1
JFK
  • 40,963
  • 31
  • 133
  • 306
  • Correction: It should be `$('body').on()` instead of `$(document).on()`. My bad. – JFK Apr 04 '12 at 21:13