I am trying to create a drag and drop of elements. I have a piece of html in the main section:
<div class="dashboard_container ui-droppable">
<div class="ab-builder-el el-empty ui-droppable" ordering="-0.5">
<p>Plaats hier je element</p>
</div>
</div>
To drop and add a piece of html (generated by some variables with php) in between the div with id=div(number) I have the following JavaScript:
//Draggable part
$('.ab-nav-element').draggable({
appendTo: '.scroll-container',
revert: 'invalid',
cursor: "move",
distance: 50,
revertDuration: 250,
helper: 'clone',
start: function(){
$('.el-empty').addClass('el-receptive');
elementName = 'standard_columns';//$(this).attr('')
},
stop: function(){
$('.el-receptive').removeClass('el-receptive');
}
});
//Droppable part
var dropContent = '<div id="div2" ordering="0"></div><div class="ab-builder-el el-empty ui-droppable" ordering="0.5"><p>Plaats hier je element</p></div>';
$('.el-empty').droppable({
hoverClass : 'ui-hover',
drop: function() {
$('.el-empty').after(dropContent);
$('#div2').load("builder-loader.php",
{
elementname: elementName,
}
);
}});
As you can see I use an AJAX call to update the content of the div.
Because I add content after, my new div's arent connected to the droppable event.
How am I able to bind the new div's to the droppable event?
The result is somewhat like this: http://jsfiddle.net/abayob/mws94soj/12/
Break your code out into functions:
var make_droppable = function($elements) {
$elements.droppable({
hoverClass : 'ui-hover',
drop: drop_function
});
}
var drop_function = function() {
var dropContent = '<div id="div2" ordering="0"></div><div class="ab- builder-el el-empty ui-droppable" ordering="0.5"><p>Plaats hier je element</p></div>';
$('.el-empty').after(dropContent);
$('#div2').load("builder-loader.php",
{
elementname: elementName,
}
);
// rebind new elements
make_droppable($('.el-empty'));
}
// call this for the first time.
make_droppable($('.el-empty'));
I misunderstood how droppable works.
In this part: "$('.el-empty').droppable({" I initialize the droppable.
The only thing I had to is create is a function that I call after the drop:
function dropreload () {$('.ab-builder-el').droppable({
hoverClass : 'ui-hover',
drop: function() {
$('.el-empty').after(dropContent);
var divId = 2;
$('#div2').load("builder-loader.php",
{
elementname: elementName,
divId:divId
}
);
dropreload();
}})};
Call the function in between the $(document).ready({}) to initialize the droppable event for the first time. The rest is done after the drops.
I guess it was a long day :)
Related
I am new to Jquery and I am having some problem with my code. My program has a container and a small menu below. I have some img elements class piece that I can drag to my container and move around. I want to drop some other img element class cap inside my dragged piece items but when I drop the cap over the piece it didn't show up. When I see the console log I can see that the element has a child element but I cannot see it. What do you think is my problem?
var x = null;
$( function () {
$(".piece").draggable({
cancel: "a.ui-icon",
revert: "invalid",
helper: 'clone',
containment: '#container',
});
$(".piece").droppable({
accept: ".cap",
drop: function( event, ui ) {
x= ui.helper.clone();
x.appendTo(this);
}
});
$(".cap").draggable({
cancel: "a.ui-icon",
helper: 'clone',
containment: '#container',
});
$("#container").droppable(
{
accept : ".piece",
drop : function(event, ui)
{
x = ui.helper.clone();
x.css("width", 200);
x.css("height", 200);
x.draggable({
containment: '#container',
cursor: 'move',
});
x.appendTo(this);
x.droppable({
accept: ".cap",
drop: function( event, ui ) {
x= ui.helper.clone();
x.css("width", 200);
x.css("height", 200);
alert(' was dropped onto me!' );
x.appendTo(this);
console.log("this");
console.log(this);
}
});
ui.helper.remove();
}
});
});
I expect the output to be the cap over the piece but the cap didn't show over the piece. You can see the fiddle at: https://jsfiddle.net/littletrives/6ktub3a9/
Your code is placing the cap inside the piece correctly, as you have noticed.
The problem is that <img> elements can not contain elements (source: img specification, content model nothing specification). Because your cap <img> is inside of the piece <img>, it is not displayed.
A solution could be to add a <div> with the src of the piece as a background-image instead of adding it as an <img> tag. That way, you could add the cap <img> inside of it.
I made a fork of your jsfiddle with a small example: https://jsfiddle.net/tp7e2no1/1/
I have 2 divs: leftDiv and mainDiv. leftDiv contains some list elements which are draggable and droppable into mainDiv. I want to make these dropped items draggable inside the mainDiv as well, but after the first drag inside this div, items become non draggable. How can I fix this? Here is my jQuery code:
$('#output li').draggable({
helper: 'clone',
revert: 'invalid'
});
$('#mainDiv').droppable({
drop: function (event, ui) {
if(ui.draggable.hasClass('foo')){
$(ui.helper).remove();
$(this).append(ui.draggable.draggable());
}
else {
var item = $('<div class="foo">').append(ui.draggable.text());
item.draggable();
$(this).append(item);
}
}
});
You can fix it like this:
$('#mainDiv').droppable({
drop: function (event, ui) {
if(ui.draggable.hasClass('foo')){
//$(ui.helper).remove();
var draggedItem = ui.draggable.draggable();
$(this).append(draggedItem);
draggedItem.draggable();
}
else {
var item = $('<div class="foo">').append(ui.draggable.text());
item.draggable();
$(this).append(item);
}
}
});
Online Demo (fiddle)
Ok, I have an issue with drag and drop.
What they do, they click a button, it initializes the whole drag and drop.
function sortElements() {
// Place droppable elements
var x = 0;
$("#content-body div[data-type='column'],#content-body div[data-type='carousel']").each(function() {
var el = $(this);
if(x == 0){
el.before('<div class="neoDroppableEle" id="neoDroppableEle-' + x + '"><\/div>');
x++;
}
el.addClass('edit_el').after('<div class="neoDroppableEle" id="neoDroppableEle-' + x + '"><\/div>');
x++;
el.append('<div class="drag-handle"><i class="fa fa-arrows"></i></div>');
var w = el.width();
el.css('width',w+'px');
});
$("#content-body div[data-type='insertable']").each(function() {
var el = $(this);
el.prepend('<div class="neoDroppableEle" id="neoDroppableEle-' + x + '"><\/div>');
x++;
});
// Swap entire columns
$("#content-body div[data-type='column']").draggable({
refreshPositions: true,
helper: "clone",
handle:'.drag-handle',
appendTo: "body",
zIndex: 10000,
start: function( event, ui ) {
$(".neoDroppableEle").addClass('dragging');
},
stop: function( event, ui ) {
$(".neoDroppableEle").removeClass('dragging');
}
});
$(".neoDroppableEle").droppable({
accept: "div[data-type='column']",
tolerance: "pointer",
hoverClass: "focus_in",
activeClass: "focus_in_active",
drop: function(event, ui) {
cur_ele = this.id;
var el = ui.draggable;
var html = el.html();
el.remove();
$("#" + cur_ele).replaceWith('<div class="row" data-type="column">'+html+'</div>');
}
});
// Swap individual photos within columns
$("#content-body div[data-type='imagewrap']").each(function(){
$(this).draggable({
revert: "invalid",
helper: "clone" ,
zIndex: 10001,
});
$(this).droppable({
accept: "div[data-type='imagewrap']",
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function( event, ui ) {
var draggable = ui.draggable, droppable = $(this);
draggable.swap(droppable);
}
});
});
}
When they are done, they click the button again.
function sortElementsComplete() {
$(".ui-droppable").droppable("destroy");
$(".ui-draggable").draggable("destroy");
$(".edit_el").removeAttr('style').removeClass('edit_el');
$(".neoDroppableEle").remove();
$(".drag-handle").remove();
}
This all runs and works great!
But now I am tryng to save the HTML code after each drop for undo's. And when I save the undo, I need to remove all additional classes and elements my function to drag and drop add's. Because they may not be in the sorting area when they click undo and do not want drag handles and my borders I set up as visual aids just appearing.
So now I have:
$(".neoDroppableEle").droppable({
accept: "div[data-type='column']",
tolerance: "pointer",
hoverClass: "focus_in",
activeClass: "focus_in_active",
drop: function(event, ui) {
cur_ele = this.id;
var el = ui.draggable;
var html = el.html();
el.remove();
$("#" + cur_ele).replaceWith('<div class="row" data-type="column">'+html+'</div>');
setTimeout(function(){
sortElementsComplete();
editor_add();
},1000);
}
});
The above with the timeout code always fails with:
Error: cannot call methods on droppable prior to initialization;
attempted to call method 'destroy'
How so? It IS initialized and running. After the drop I should be able to destroy it, make my save and rebuild it. Using disable gives the same error. To me the error makes no sense.
After editor_add() is ran, it re-builds whatever they were doing, in this case it will fire sortElements(); after the save.
But the below runs fine?
// Swap individual photos within columns
$(this).droppable({
accept: "div[data-type='imagewrap']",
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function( event, ui ) {
var draggable = ui.draggable, droppable = $(this);
draggable.swap(droppable);
setTimeout(function(){
sortElementsComplete();
editor_add();
},250);
}
});
It will error if I do not have the timeout above. Seems 250 is the min, anything lower it errors. But the first one will not ever work, no matter how long or short I make the timeout.
Really hope this makes sense.
Maybe if I used
var draggable = ui.draggable, droppable = $(this);
draggable.swap(droppable);
On it instead it would work. o.O
I am trying to use the jquery-ui draggable to make some element draggable.
I set the helper option to clone the current element.
It's making the clone correctly but when I drop the clone disappears. It doesn't stay at the dragged place.
See this for Demo Fiddle Link
$('#drag').draggable({
helper: function (e, ui) {
return $(this).clone();
}
});
What am I missing ?
There maybe a simpler way, but through data of draggable, you can target a property that deals with this. Like this:
stop : function(e, ui){
$('#drag').draggable().data()["ui-draggable"].cancelHelperRemoval = true;
}
fiddle: http://jsfiddle.net/n10ucrLd/
I think there's been a lot of troubles with helper: 'clone'. I always got it to work, when I defined a droppable as well. E.g.:
HTML:
<div id="drag">Drag This</div>
<div class="container"></div>
JavScript:
$('#drag').draggable({
helper: function (e, ui) {
return $(this).clone(true);
}
});
$( ".container" ).droppable({
drop: function (event, ui) {
ui.draggable.clone().appendTo($(this)).draggable();
}
});
Live example: http://jsbin.com/vibeqaganu/1/edit?html,css,js,output
I'm building some sort of a playlist creator. I have some items the user can choose from and a horizontal sortable timeline area to drop those items on.
The Draggable:
$(".Name:not(#Add a .Name)").draggable({
revert: 'invalid',
start: function(){
$('#MainPage').css('cursor', '-moz-grabbing');
$(".Name").css('cursor', '-moz-grabbing');
},
// helper: "clone",
helper: function() {
return $("<div class='"+$(this).parent().attr('class')+"' id='"+$(this).parent().attr('id')+"'><div class='"+$(this).attr("class")+"' id='"+$(this).attr("id")+"'>"+ $(this).attr("class").split(' ')[1] +"</div></div>");
},
stop: function() {
$('#MainPage').css('cursor', 'auto');
$(".Name").css('cursor', '-moz-grab');
},
connectToSortable: "#TimelineDrop",
appendTo: '#MainPage',
containment: 'DOM',
zIndex: 800,
addClasses: false
});
The Sortable:
$("#TimelineDrop").sortable({
over: function(event, ui) {
var Breite = ((TimeSpace*5)/(TimeSpace/(currentspacing+24)))-2;
$("#TimelineDrop").append("<div class='TimelineMarker' style='width:"+ Breite +"px;'>\u00A0</div>");
},
receive: function(event, ui) {
dropped=true;
AddElementToTimeline($(this), event, ui, dropped);
},
start: function( event, ui ){
$('#MainPage').css('cursor', '-moz-grabbing');
$('.TimelineElement').css('cursor', '-moz-grabbing');
drag=true;
},
axis: "x",
stop: function( event, ui ){
$('#MainPage').css('cursor', 'auto');
$('.TimelineElement').css('cursor', '-moz-grab');
database.updateElementPosition($('.TimelineElement').index($(ui.item)), $(ui.item).children('.TimelineElementTitle').attr('id').split('D')[1], GET('id'));
drag=false;
}
});
I tried all kinds of different stuff but can't get it to work propperly. What would like to be able to is drag items from the available area to the timeline und drop them between allready appended ones. So far the helper allways get appended (vertically) above the existing elements and when I drop it the final element get append at the very last position. I hope It's clear what I'm trying to archive...
I have a fiddle right here:
http://jsfiddle.net/5SBax/4/
I want the marker to be displayed where the element will be added (between others). And I need to get rid of the helper element which also get added every time...
Take a look at this fiddle. I'm not quite sure what you are asking, but this is a good example of drag and drop capabilities. I can't comment, and I am not quite sure what you are asking. But best of luck to you!
http://jsfiddle.net/cuhuak/4CHDZ/
function FieldType(typeName, name) {
var self = this;
self.TypeName = ko.observable(typeName || "");
self.Name = ko.observable(name || this.TypeName());
self.createField = function () {
return new Field(
{
Name: this.Name(),
TypeName: this.TypeName()
}
);
}
self.onDragStart = function(event, ui) {
dropFieldType = ko.utils.domData.get(this, "ko_drag_data");
};
self.onDragStop = function(event, ui) {
dropFieldType = null;
};
}