$("li").draggable({
helper: "clone"
});
$("#div1").droppable({
drop: function (event, ui) {
$("<p></p>").appendTo("#div1");
}
});
I have objects in a list that can be dragged and dropped into a div named div1. But when I drop one into the div i don't want to be able to drop another into it. I have tried using, for, if and while loops with a count.
Here is a full solution, it allows only one item dropped, but also, if one exists, it gets replaced on the next drop with the new one. (Usefull if someone changes their mind. Just call
refreshDragDrop(dragClassName,dropDivId);
refreshDragDrop = function(dragClassName,dropDivId) {
$( "." + dragClassName ).draggable({
connectToSortable: "#" + dropDivId,
helper: "clone",
revert: "invalid"
});
$("#" + dropDivId).droppable({
accept: '.' + dragClassName,
drop: function (event, ui) {
var $this = $(this),
maxItemsCount = 1;
if ($this.children('div').length == maxItemsCount ){
//more than one item,just replace
$(this).html($(ui.draggable).clone());
} else {
$(this).append($(ui.draggable).clone());
}
}
});
}
This should help:
drop: function (event, ui) {
var $this = $(this),
maxItemsCount = 1;
if ($this.children('li').length > maxItemsCount ){
ui.sender.draggable('cancel');
alert("To much items!");
}
}
Related
On this script I have drag and drop fieldsets (left menu - top). Drag multiple fieldsets into the right "working area". In those fieldsets is an area for dropping Fields (of which I have one, left menu - bottom). Drop "Field One" into any of the dropped Fieldset (under the line in the "Drop Fields Here" area) in the working area.
I want to then move that Field One from the Fieldset I dropped it into and into the other Fieldset in the working area. I have got the Field One draggable but I cannot get it to append to the new Fieldset.
I am not wanting to delete the Field and replace it with another clone from the left menu. I am new to jquery so my code may be a bit messy. Any help is greatly appreciated. Jsfiddle and code below.
I believe the code issue is between line 21-29...but I am not sure.
JsFiddle Link
$(document).ready(function() {
var fs_count = 0;
$("#drop-area").droppable({
accept: '.ui-draggable:not(.draggableField , .activeField)',
drop: function(event, ui) {
fs_count++;
var clone = $(ui.draggable).clone()
clone.addClass('.connectedSortable')
// clone.removeClass('.ui-draggable');
if (clone.hasClass('dropped')) {
return false;
}
clone.addClass('.connectedSortable').addClass('dropped').attr('id', 'fs_' + fs_count);
$(this).append(clone);
var fs_class = clone.attr('class');
alert('You added a field with class ' + fs_class);
var fieldsDroppable = $('#drop-area .ui-draggable:last-child .fieldDroppable');
fieldsDroppable.droppable({
accept: '.draggableField , .activeField',
drop: function(event, ui) {
var clone = $(ui.draggable).clone();
if (clone.hasClass('draggableField')) { // If else to prevent clones reproducing in Fieldsets when moving from original Fieldset.
clone.removeClass('ui-draggable , draggableField').addClass('activeField');
$(this).append(clone);
}
else {
// Append the div here?
}
var cloneClass = clone.attr('class'); // Temporary varialble for develpoment alert below
alert('you dropped a field' + cloneClass); // Temporary for development only
// Below re-register the "field" with jquery....not sure this is entirely correct.
var fieldsDraggable = $('#drop-area .ui-draggable .fieldDroppable .activeField');
fieldsDraggable.draggable();
}});
} });
$(".fieldDroppable").droppable({
accept: '.draggableField , .activeField',
drop: function(event, ui) {
var clone = $(ui.draggable).clone()
$(this).append(clone);
}
});
$(".ui-draggable").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'invalid'
});
$(".draggableField").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'false'
});
$(".activeField").draggable();
$("#drop-area").sortable({
handle: '.drag-handle',
update: function () { //triggered when sorting stopped
var dataAuto = $("#drop-area").sortable("serialize", {
key: "za",
attribute: "id",
});
alert(dataAuto);
}
});
$("#drop-area").disableSelection();
});
There will be a lot of work to do here, yet you can get over this hurdle like so:
https://jsfiddle.net/Twisty/6trmrfoo/32/
Basically, you want to assign a new .droppable() to a specific element in the field set when it is added to the #drop-area. I would advise using a function as you will do this a multitude of times.
You can also make use of .data() to store a source value along with the draggable elements. I only did this for fields since that was the only pace it seemed like it was needed. You can updated this once it's dropped into a fieldset so that future drag-n-drop operations can be handled properly, we don't want to clone the object we move it.
To move it, consider using .detach(). It'll detach the element from the current parent and can be used in chain to append or move into memory as a variable. Similar to .clone() just we're manipulating the actual object. .clone() is to "Copy & Paste" as .detach() is to "Cut & Paste".
JavaScript
$(function() {
var fs_count = 0;
function makeFieldTarget($fs) {
$fs.droppable({
accept: '.draggableField, .activeField',
drop: function(event, ui) {
var clone, cloneClass;
if (ui.draggable.data("source") == "sidebar") {
clone = $(ui.draggable).clone();
clone.removeClass('draggableField').addClass('activeField');
$(this).append(clone);
cloneClass = clone.attr('class');
console.log('DROPFIELD - you dropped a field from the side bar: ' + cloneClass);
clone.data("source", "fieldset").draggable({
zIndex: 1000
});
}
if (ui.draggable.data("source") == "fieldset") {
clone = ui.draggable;
clone.detach().attr("style", "").appendTo($(this));
cloneClass = clone.attr('class');
console.log('DROPFIELD - you dropped a field from a Field set: ' + cloneClass);
}
}
});
}
$("#drop-area").droppable({
accept: '.ui-draggable:not(.draggableField, .activeField)',
drop: function(event, ui) {
fs_count++;
var clone = $(ui.draggable).clone()
clone.addClass('connectedSortable');
if (clone.hasClass('dropped')) {
return false;
}
clone.addClass('connectedSortable dropped').attr('id', 'fs_' + fs_count);
$(this).append(clone);
var fs_class = clone.attr('class');
console.log('DROPAREA - You added a field with class ' + fs_class);
makeFieldTarget(clone.find(".fieldDroppable"));
$("#drop-area").sortable("refresh");
}
});
$(".ui-draggable").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'invalid'
});
$(".draggableField").data("source", "sidebar").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'false',
zIndex: 1000
});
$("#drop-area").sortable({
handle: '.drag-handle',
placeholder: "drop-place-holder",
items: ">div.dropped",
update: function() { //triggered when sorting stopped
var dataAuto = $("#drop-area").sortable("serialize", {
key: "za",
attribute: "id",
});
alert(dataAuto);
}
});
$("#drop-area").disableSelection();
});
I made a drag & drop system. The draggable items can be dropped in placeholders. Those placeholders are added dynamically based on the amount of draggable items.
But when I drag a draggable item between those placeholders, it doesn't get appended to it. I've tried many many things but I'm still stuck on it.
I'm afraid that I'll need to change a lot of the code, but maybe one of you has a genius idea on how to solve this.
Here's the jsfiddle
Is it possible to check wether it has been placed on a placeholder, or not?
This is my droppable function:
function dropping () {
$("li.placeholder").droppable({
accept: ".to-drag",
hoverClass: correct_placeholder,
activeClass: active_placeholder,
revert: false,
tolerance: "pointer",
drop: function (event, ui) {
var dragging = ui.draggable.clone().find("img").remove();
$(this).append(dragging).addClass("dropped");
$(this).droppable('disable');
var day = $(ui.draggable).attr('data-id');
var index = $(event.target).index();
$(this).attr("data-id", day);
$(this).attr("date-order", index);
$(this).addClass("drop-"+ index);
$(this).attr("data-content", "");
$(this).find("h1, p").remove();
var dropped = $(".dropped").length;
var original = $(".placeholder").length;
if (dropped === original) {
$("li.placeholder").removeClass(blank_placeholder);
$("#dropzone").append('<li class="placeholder ' + blank_placeholder +' " data-id="" data-order=""></li>');
init();
}
$(".remove").click(function() {
var removable = $(this).parent();
var modal = $(this).attr("data-modal");
$(".modal-"+modal).remove();
if (dropped > original) {
$(this).parent().droppable('enable')
removable.remove();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
} else {
$(this).parent().droppable('enable');
removable.empty();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
}
init();
});
}
});
$("li.dropped").droppable({
disabled: function (event, ui) {
disabled: true
}
});
}
I want to create a jquery drag and drop like below
1) I can drag a element with the class doDrag
2) I can drop that doDrag into a div called #content
3) Also doDrag elements should be able to drop into the older doDrag divs which were dropped before into the #content div
I did it like below. But got issues.
$(".doDrag").draggable({
helper:"clone"
});
makeDroppable($("#content"));
function makeDroppable(elements) {
console.debug(elements);
$(elements).droppable({
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function (event, ui) {
var uuid = guid();
$(this).append("<div style='border:2px solid;height:50px;width:400px;' id='" + uuid + "'>Drop</div>");
makeDroppable($("#" + uuid));
return false;
}
});
}
What happened was drop event is calling multiple times.
Can anyone help me on this please
Finally found the answer.
what i had to do is add greedy:true
elements.droppable({
greedy: true,
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function (event, ui) {
console.debug($(this));
var uuid = guid();
$(this).append("<div style='border:2px solid;height:50px;width:400px;' id='" + uuid + "'>Drop</div>");
makeDroppable($("#" + uuid));
return false;
}
});
I need someone to help me with jQuery draggable and droppable.
Push/Pop values to Like/Hate Array when items drop and drag away.
When the items leave Like/Hate boxes, they can go back to where they come from, the correct div box.
I don't understand why when I drap/drop the boxes show me 2 names for a item, though now I can use $.unique() but it is not practice at all. And I have try many ways but not sure how to pop values out of Like/Hate Array when items are taken out.
Thank you very much!
My code is here
Like = [];
Hate = [];
$(function () {
$("#AllTable .test").draggable({
appendTo: "body",
helper: "clone",
revert: "invalid",
});
$(".LikeBox div").droppable({
drop: function (event, ui) {
var $item = ui.draggable;
$item.appendTo("#likeTable");
var ingre = $item.text();
alert(ingre);
Like.push(ingre);
Like = $.unique(Like)
}
});
$(".HateBox div").droppable({
drop: function (event, ui) {
var $item = ui.draggable;
$item.appendTo("#hateTable");
var ingre = $item.text();
Hate.push(ingre);
Hate = $.unique(Hate)
}
});
$(function () {
$('.IngreMainCat').accordion();
});
});
Edit:
My new code is this, problem 1 solved:
Like = [];
Hate = [];
$(function() {
$( "#AllTable .test" ).draggable({
appendTo: "body",
helper: "clone",
revert: "invalid",
});
$( ".LikeBox .droptrue" ).droppable({
drop: function( event, ui ) {
var $item = ui.draggable;
$item.appendTo("#likeTable");
var ingre = $item.text();
Like.push(ingre);
if($.inArray(ingre,Hate) > -1){
var index = Hate.indexOf(ingre);
if (index > -1) {
Hate.splice(index, 1);
}
}
}
});
$( ".HateBox .droptrue" ).droppable({
drop: function( event, ui ) {
var $item = ui.draggable;
$item.appendTo("#hateTable");
var ingre = $item.text();
Hate.push(ingre);
if($.inArray(ingre,Like) > -1){
var index = Like.indexOf(ingre);
if (index > -1) {
Like.splice(index, 1);
}
}
}
});
});
You actually have 2 divs that are droppable because of your selector. Since you call all child divs of .LikeBox you get these 2 droppables that each run the drop function:
<div>
<div id="likeTable" class="droptrue">
After droppable is called it looks like this, see ui-droppable on both:
<div class="ui-droppable">
<div id="likeTable" class="droptrue ui-droppable">
Clarify your selector and you shouldn't have the problem. Like this for example:
$( ".LikeBox .droptrue" ).droppable({
see working fiddle: https://jsfiddle.net/2ets9hjg/
EDIT:
For the elements to remove from your arrays, a suggestion: instead of using push and pop and keep track of what you add and remove in the tables, you can map you tables when you need them. See jquery map: http://api.jquery.com/jquery.map/. It's easier to keep track that way. Like this:
Like = $.map($( "#likeTable div" ),function(a){return a.textContent});
https://jsfiddle.net/2ets9hjg/4/
I've a peculiar situation. I have two lists. 1 list contains all items, and 2 contains top list. Obviously items overlap, and items in the second list are marked with class clone-23 clone-25 according to which element from list 1 are they cloned from.
Example:
List 1
1 run
2 eat
3 drink
4 play
List 2 (TOP)
1 run (class clone)
2 eat (class clone)
When re-arranged data is saved to DB.
I would like to avoid refresh and re-pulling of data from DB. So I would like to sync position of elements in two lists.
So whenever user drags around item in list 1, list 2 automatically shows changed positions and vice versa.
I initiate my sortable:
// Initiate jquery ui sortable
$(".word-list").sortable({
tolerance: 'pointer',
cursor: 'move',
forcePlaceholderSize: true,
dropOnEmpty: true,
connectWith: 'ol.word-list',
//containment: "body",
//
start: function(event, ui) {
// Starting position of the word element
//ui.item.startPos = ui.item.index();
//console.dir(ui.item.startPos);
},
//
stop: function(event, ui) {
//
},
update: function(event, ui) {
//
save_word_order(this);
//
},
out: function(event, ui) {
//
},
over: function(event, ui) {
//
},
placeholder: "ui-state-highlight"
});
Clone element html:
<li data-con-id="94" data-order-id="1" data-note="" class="ui-state-default clone-94"</li>
Lists are simply:
<ol id="tabs-1" class="word-list"></ol>
<ol id="tabs-2" class="word-list"></ol>
Any thoughts?
See this fiddle for code which syncs the order of items common to both lists:
http://jsfiddle.net/Fresh/22jc2/
Note that in my example I have simplified list two's li elements by not including the clone attributes; instead I am comparing items in both list by the list item's innerText value. It should be fairly easy for you to refactor my solution to use the clone item attributes if you really need to use them.
The script which I've used to achieve the synchronisation of the order of the common list items is:
var reorderLists = function (list1, list2) {
$('#' + list1 + ' li').each(function (index) {
var sortableItemWithText = $('#' + list2 + ' li:contains(' + this.textContent + ')');
if (sortableItemWithText.length === 1) {
sortableItemWithText.appendTo('#' + list2);
return;
}
});
};
$("#sortable1, #sortable2").sortable({
update: function (event, ui) {
var parentNodeId = ui.item[0].parentNode.id;
if (parentNodeId == "sortable1") {
reorderLists("sortable1", "sortable2");
}
if (parentNodeId == "sortable2") {
reorderLists("sortable2", "sortable1");
}
}
});
$("#tabs").tabs();
Note that the syncing of the order of common list items works if you change the position of items in either list 1 or list 2.
Also note that by commenting out:
$("#tabs").tabs();
You'll be able to see the lists updating automatically when you move the list items; this makes it easier to confirm that the re-order routine is work as expected.
perhaps this can help :
See this fiddle for code which syncs the order of items common to both
lists:
http://jsfiddle.net/penjepitkertasku/6bk7B/1/
$(function() {
var dragElementID = "";
var dropElementID = "";
var dragElementItemName = "";
var allElementItemName = "";
$(".word-list").sortable({
tolerance: 'pointer',
cursor: 'move',
helper: 'clone',
//revert: 'invalid',
forcePlaceholderSize: true,
dropOnEmpty: true,
connectWith: 'ol.word-list',
start: function(e, ui){
var id = $('ol.word-list').children().index($(ui.item[0]));
var name = $('ol.word-list').children(':eq(' + id + ')').text();
dragElementItemName = name;
dragElementID = this.id;
},
stop: function(event, ui) {
var id = $('ol.word-list').children().index($(ui.item[0]));
//validate
if(dragElementID == dropElementID) { return; }
if(id == -1)return;
if(dragElementID == "tabs-1")
{
if(allElementItemName.indexOf(dragElementItemName,1) > 0) { $(this).sortable('cancel'); return; }
var elm = $(ui.item[0]).clone(true).removeClass('box ui-draggable ui-draggable-dragging').addClass('box-clone');
$('ol.word-list').children(':eq(' + id + ')').after(elm);
$(this).sortable('cancel');
}else{
ui.item.remove();
}
},
update: function(event, ui) {
//
//save_word_order(this);
//
},
out: function(event, ui) {
//
},
over: function(event, ui) {
//
dropElementID = this.id;
allElementItemName = '|' + $('#' + dropElementID + ' li').text() + '|';
},
placeholder: "ui-state-highlight"
});
});