Change HTML when on start dragging with Jquery UI - jquery-ui

I've been working on a drag and drop UI with jquery UI.
I have a bunch of elements like this, that are draggable:
<i class="fa fa-laptop fa-fw"></i> Server
I can drag and clone this onto a drop zone. But when I start dragging the original element, I want to change the HTML to be
<i class="fa fa-laptop fa-5"></i>
The current code looks like this, but should I be doing something in the start event handler to clone, and change the html of the cloned element?
function MakeDraggable(ele) {
ele.draggable({
grid: [20, 20 ],
//revert: "invalid",
helper: 'move'
});
}
$(function() {
// Make the .draggable class a Draggable
//
$( ".draggable" ).draggable({
grid: [ 20, 20 ],
helper: 'clone',
appendTo: '#dropzone-panel',
start: function(event, ui) {
console.log("Dragging me.....");
}
});
// Setup the dropzone
//
$("#dropzone-panel").droppable({
drop: function(event, ui) {
console.log("Drop Event Fired");
// Get the original element id
var id = ui.draggable.attr("id");
// If this element is a copy already
// then dont clone it.
//
if (id.indexOf("-copy-") >= 0) {
console.log("This is a copy");
} else {
// This is the orginal, so clone and create a new id
var number_of_clones = document.querySelectorAll('*[id^="'+id+"-copy-" +'"]').length;
console.log("found [" +number_of_clones +"] copies");
var pos = ui.position;
var $obj = ui.draggable.clone().attr("id", id+"-copy-"+number_of_clones);
$obj.css({
position: 'absolute',
top: pos.top + "px",
left: pos.left + "px"
});
$obj.appendTo("#dropzone-panel");
// Make the clone draggable
MakeDraggable($obj);
}
}
});

Related

Jquery UI drag and drop - dragged item dissapears when dropped only on mobile

I am trying to get drag and drop working properly and on desktop of laptop pc it is fine. However, on a mobile device, when I drag and drop, when dropped, the dragged item dissapears underneath (i think) everything else and I really am unable to work out why.
I have uploaded a page showing the problem to http://mailandthings.co.uk/dam1/
I have tried setting the zindex in the draggable code and that makes no difference
var $dragContainer = $("div.drag-container");
var $dragItem = $("div.drag-item");
$dragItem.draggable({
cursor: "move",
snap: "div.drag-container",
snapMode: "inner",
snapTolerance: 10,
helper: "clone",
handle: "i",
zIndex: 10000
});
$dragContainer.droppable({
drop: function (event, ui) {
var $elem = $(event.toElement);
var obj = {
posX: event.pageX - $dragContainer.offset().left - event.offsetX,
posY: event.pageY - $dragContainer.offset().top - event.offsetY,
data: $elem.data(),
html: $elem.html()
};
addElement(obj);
masterPos.push(obj);
}
});
function addElement(obj) {
var $child = $("<div>");
$child.html("<i>" + obj.html + "</i>").addClass("drop-item drop-item-mobile");
$child.attr("data-type", obj.data.type);
$child.css({
top: obj.posY,
left: obj.posX
});
$dragContainer.append($child);
}
If it using jQuery UI Touch Punch 0.2.3
Does anyone have any ideas?
There was sort of a logistical issue that I found. Based on your code, I could identify the following state / logic:
User drags an item (A, B, C) to the car image to indicate a Dent, Scratch, or Heavy Damage
The Drop Point indicates where the Type of damage is located
When the dragged item is dropped, a new object should be created that indicates the Type and stores the location on the car map
This new object replaces the dragged item and is appended to the container
To expand on this, you have the following code that is the dragged element, for example:
<div class="drag-item ui-draggable" style="">
<i data-type="A" class="ui-draggable-handle">A</i>Dent
</div>
This is important when creating the new object. In your current code, you're requesting data from an object that does not have any data attributes, $elem.data(). Remember that this is the <div> that contains the <i> that has the attribute. So data is null or undefined. You will want to capture the data from the child element: $elem.find("i").data().
Also, since you append all the HTML to your new object, you make a double wrapped element. $child will look like:
<div class="drop-item drop-item-mobile">
<i>
<div class="drag-item ui-draggable" style="">
<i data-type="A" class="ui-draggable-handle">A</i>Dent
</div>
</i>
</div>
I do not think this was your intention. I suspect your intention was to create:
<div class="drop-item drop-item-mobile">
<i>A</i>
</div>
Here is an example of all this: https://jsfiddle.net/Twisty/g6ojp4ro/40/
JavaScript
$(function() {
var theForm = document.forms.form1;
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
var masterPos = [];
$("#hidpos").val('');
var $dragContainer = $("div.drag-container");
var $dragItem = $("div.drag-item");
$dragItem.draggable({
cursor: "move",
snap: "div.drag-container",
snapMode: "inner",
snapTolerance: 10,
helper: "clone",
handle: "i",
zIndex: 10000
});
$dragContainer.droppable({
drop: function(event, ui) {
var $elem = ui.helper;
var type = ui.helper.find("i").data("type");
var $child = $("<div>", {
class: "drop-item drop-item-mobile"
}).data("type", type);
$("<i>").html(type).appendTo($child);
$child.appendTo($dragContainer).position({
of: event
});
var obj = {
posX: $child.offset().top,
posY: $child.offset().left,
data: $child.data(),
html: $child.prop("outerHTML")
};
masterPos.push(obj);
}
});
$("map").imageMapResize();
// Save button click
$('#form1').submit(function(e) { //$("#btnsave").click(function () {
if (masterPos.length == 0) {
$("#spnintro").html("Oops!");
$("#spninfo").html("No position data was entered");
$("#dvinfo").fadeTo(5000, 500).slideUp(500, function() {});
} else {
$("#hidpos").val(JSON.stringify(masterPos));
$.ajax({
url: '/handlers/savepositions.ashx',
type: 'POST',
data: new FormData(this),
processData: false,
contentType: false,
success: function(data) {
$("#spnintro").html("Success!");
$("#spninfo").html("Position data has been saved");
$("#dvinfo").fadeTo(5000, 500).slideUp(500, function() {});
}
});
}
e.preventDefault();
});
});
Tested with Mobile client at: https://jsfiddle.net/Twisty/g6ojp4ro/40/show/ and is working as expected.
Hope that helps.

jquery ui drop not working with helper clone

I have a simple drag and drop using jquery ui. I want to clone the element and drop the clone at the cursor position.
$(function() {
$( "#draggable" ).draggable({
grid: [ 20, 20 ],
//helper: 'clone',
});
$("#dropzone-panel").droppable({
drop: function(event, ui) {
console.log("Drop Event Fired");
}
});
});
I can drag the element and when I drop it, it stays in the correct position.
But I don't want to move the original, I want to clone it, and then drop the clone in place.
I tried calling clone and adding an appendTo in the drop function, but this just appends it to the end of the #dropzone-panel, rather than leaving it in place.
Any idea what I need to do, to clone and drop at the cursor position?
I would setup the draggable with the helper option and then the droppable with the accept option. This might look like:
$(function() {
$(".draggable").draggable({
helper: 'clone',
grid: [ 20, 20 ],
appendTo: ".droppable"
});
$(".droppable").droppable({
accept: ".draggable",
drop: function(e, ui) {
var pos = ui.position;
var $obj = ui.helper.clone();
$obj.css({
position: 'absolute',
top: pos.top + "px",
left: pos.left + "px"
});
$obj.appendTo(".droppable");
}
});
});
You will want to make use of CSS to wrap your Droppable in a Div that has position: relative; to ensure that the absolute positioning of the appended element is maintained.

Stop sort and change css

I have 3 sortable divs. I try to change the height of an item if the user moves it to the right (without sorting). It works well in "sort" this is when the user is moving the item, but when the user leaves the item it comes back to its original height (40px) and I want it to keep the new one (20px). Is it possible to do that?
(Of course I could just put no condition in stop but this is a simplified case and I need a way to detect if in sort the user has moved the item)
$("#sortable").sortable({
sort: function (event, ui) { // during sorting
var move = (ui.position.left - ui.originalPosition.left);
$('#desti').text(move);
if ( move > 30 ) {
ui.item.css({height:'20px'});
}
},
stop: function(event, ui) {
if ( move > 30 ) {
ui.item.css({height:'20px'});
}
}
});
HTML:
<div id="sortable">
<div>item1</div>
<div>item1</div>
<div>item1</div>
</div>
CSS:
#sortable div {
height:40px;
margin-bottom:3px;
background:blue;
}
At first look at your code you are using move variable but it is declared inside sort: function
If you declare move inside sort:, how could you use it in stop:
$("#sortable").sortable({
sort: function (event, ui) { // during sorting
var move = (ui.position.left - ui.originalPosition.left);// Look At Here
$('#desti').text(move);
if ( move > 30 ) {
ui.item.css({height:'20px'});
}
},
stop: function(event, ui) {
if ( move > 30 ) {
ui.item.css({height:'20px'});
}
}
});
Just declare it like this...
var move =0;//Declare it here.. or create another move inside stop:
$("#sortable").sortable({
sort: function (event, ui) { // during sorting
move= (ui.position.left - ui.originalPosition.left);
$('#desti').text(move);
if (move > 30) {
ui.item.css({ height: '20px' });
}
},
stop: function (event, ui) {
//create a move here...
if (move > 30) {
ui.item.css({ height: '20px' });
}
}
});

jquery/jquery ui: find each span add class to single span being dragged

I'm trying to make it so only the span that is being dragged has a class added, so far I have this but but it adds the class to all span's ...
$(function() {
$('span').draggable();
$('#container, #board').droppable({
tolerance : 'touch',
over : function() {
$('li').each(function() {
$(this).find('span').addClass('over');
});
},
drop : function() {
$('li').each(function() {
$(this).find('span').removeClass('over');
});
}
});
});
Here's the he HTML (if that helps)
<div id="container">
<div id="board">
<ul>
<li class="foo1"><span class="p1"></span></li>
<li class="foo2"><span class="p1"></span></li>
<li class="foo1"><span class="p1"></span></li>
<li class="foo2"><span class="p1"></span></li>
</ul>
</div>
</div>
you can use the start event to add the class to the element being dragged.
$('span').draggable({
start: function(event, ui) {
$(event.target).addClass('over');
}
});
and to remove it again when no longer dragged simply add a handler to the stop event as well
$('span').draggable({
start: function(event, ui) {
$(event.target).addClass('over');
},
stop: function(event, ui) {
$(event.target).removeClass('over');
}
});
You don't need the each(), just do $(this), which refers to the current element, and it should work:
over : function() {
$(this).find('span').addClass('over');
}
$(function() {
$('span').draggable();
$('#container, #board').droppable({
tolerance : 'touch',
over : function() {
$(this).find('li span').addClass('over');
},
drop : function() {
$(this).find('li span').removeClass('over');
}
});
});
$('#container, #board').droppable({
tolerance : 'touch',
over : function(e, elem) { // Params
// here is the original element we move
$(elem.draggable).find('span').addClass("over");
},
drop : function(e, elem) {
//
$(elem.draggable).find('span').removeClass('over');
however if you dont use original Dom when it is been dragging (ie. {helper: "clone" }), elem.draggable wont affect your helper. thats write your .draggable code here...
and also you can try "elem.helper"

jquery drag and drop function

This function takes an li element and adds it to another ul element. After this code is fired the jquery events attached to the children spans of the li element do not fire the first time they are clicked.
function AddToDropBox(obj) {
$(obj).children(".handle").animate({ width: "20px" }).children("strong").fadeOut();
$(obj).children("span:not(.track,.play,.handle,:has(.btn-edit))").fadeOut('fast');
$(obj).children(".play").css("margin-right", "8px");
$(obj).css({ "opacity": "0.0", "width": "284px" }).animate({ opacity: "1.0" });
if ($(".sidebar-drop-box ul").children(".admin-song").length > 0) {
$(".dropTitle").fadeOut("fast");
$(".sidebar-drop-box ul.admin-song-list").css("min-height", "0");
}
if (typeof SetLinks == 'function') {
SetLinks();
}
if(document.getElementById("ctl00_cphBody_hfRemoveMedia").value===""||document.getElementById("ctl00_cphBody_hfRemoveMedia").value===null)
{
document.getElementById("ctl00_cphBody_hfRemoveMedia").value=(obj).attr("mediaid");
}
else
{
var localMediaIDs=document.getElementById("ctl00_cphBody_hfRemoveMedia").value;
localMediaIDs= localMediaIDs.replace((obj).attr("mediaid"),"");
document.getElementById("ctl00_cphBody_hfRemoveMedia").value=localMediaIDs+", "+(obj).attr("mediaid");
}
}
Is there something missing in this code that would cause that?
UPDATE
thats exactly what I am using for the jquery sortable feature that actually calls the addtoDropbox Method().
// Make our dropbox a selectable & sortable.
$(".sidebar-drop-box ul").sortable({
connectWith: '.admin-left',
tolerance: "intersect",
handle: ".handle",
opacity: "0.5",
receive: function(event, ui) {
**AddToDropBox(ui.item)**;
},
start: function(event, ui) {
$(".sidebar-drop-box ul.admin-song-list").css("min-height", "70px");
isDraggingSong = true;
//soundManager.stopAll();
//$(".btn-stop").removeClass("btn-stop");
},
stop: function(event, ui) {
if ($(".sidebar-drop-box ul").children("li").length == 0) {
$(".dropTitle").fadeIn();
}
}
}); //.selectable({ filter: 'li', cancel: '.btn-stop,.btn-play,.notes,.btn-del,span.remove' });
// Do the same for our playlist.
$(".admin-left").sortable({
opacity: '0.5',
tolerance: "intersect",
handle: ".handle",
appendTo: 'appentToHolder',
items: "li.admin-song",
update: function(event, ui) {
$(ui.item).css("opacity", "0.0").animate({ opacity: "1.0" }, "medium");
if ($.browser.msie && $.browser.version == "7.0") {
$(ui.item).css("margin-bottom", "-6px");
}
},
receive: function(event, ui) {
AddToLeftList(ui.item);
},
start: function(event, ui) {
$(".admin-left li.ui-selected").removeClass("ui-selected");
isDraggingSong = true;
//soundManager.stopAll();
//$(".btn-stop").removeClass("btn-stop");
},
stop: function(event, ui) {
CheckLeftList();
},
connectWith: '.sidebar-drop-box ul'
}).selectable({ filter: 'li.admin-song', cancel: '.head *,.btn-stop,.btn-play,.notes,.btn-del,span.remove' }); // added .head * to fix bug# 1013
the bold line calls the function I added previously, which places the li element.
I am not sure exactly where the disconnect happens, but i know between these 2 code segments that it breaks something and the next click doesn't not work on the source ul. i ahve been struggling with this for days. I cant turn this back to my boss this shape...lol
thanx
It doesn't look like this function is adding something to a list.
This function first does a couple of
CSS changes to obj and it's
descendants.
Then it goes and calls the global
function SetLinks (if it is
defined).
And thirdly it sets the value of
the element
"ctl00_cphBody_hfRemoveMedia", which
is probably some kind of input.
Looks like this was pasted together from at least two other functions and would need refactoring.
I'm guessing that the cause for your lost events might be somewhere near a call to AddToDropBox.

Resources