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();
}
});
});
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/
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.
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
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
});
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.
Please try change
$('body').append(itemToAdd)
to
$('body').append(itemToAdd).find('.draggable').draggable()
Or
$('body').append(itemToAdd);
$('.draggable').draggable();
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.
With this workaround, you don't need to call the plugin again after adding in new elements as suggested.