Jquery UI Draggable: Align helper to mouse position - javascript

With jQuery I have a draggable element. It's a div with a size of 200 x 40.
Of course the user can start dragging this div by clicking at variuos positions in the div.
What I want is when the startdrag event happens, the helper (clone) div will always be aligned to the cursor the same way, no matter where in the div the user started dragging.
So after the mousedown the helper's top and left values need to be the same as the mouses x and y. I've tried this using this coffeescript code:
onStartDrag: ( e, ui ) =>
ui.helper.css
left: e.clientX
top: e.clientY
console.log( e )
But it doesn't work and my guess is that this is happening because the values I put in are directly overwritten by the draggable plugin because of mouse movement..
Any ideas?

After trying Amar's answer and realizing that it screws up interactions with droppable, I dug deeper, and found that there is an option specifically to support this called cursorAt.
$('blah').draggable
helper: ->
... custom helper ...
cursorAt:
top: 5
left: 5
This places the top-left corner of the helper 5 pixels above and to the left of the cursor, and interacts correctly with droppable.
http://api.jqueryui.com/draggable/#option-cursorAt
And let's give credit where credit is due. Thanks, jquery-ui mailing list archives!
https://groups.google.com/forum/#!topic/jquery-ui/Evb94G_QvNw

Try setting like this,
start: function (event, ui) {
$(ui.helper).css("margin-left", event.clientX - $(event.target).offset().left);
$(ui.helper).css("margin-top", event.clientY - $(event.target).offset().top);
}
Take a look at this jqFAQ.com , it will be more helpful for you.

I've found a fix for this and it's very easy, if you are using the sortable plugin you can fix the helper position like this:
sort: function(e, ui) {
$(".ui-sortable-handle.ui-sortable-helper").css({'top':e.pageY});
}

I Agree with #roverv.
This works fine form me.
$('.js-tire').draggable
tolerance: 'fit',
appendTo: 'body',
cursor: 'move',
cursorAt:
top: 15,
left: 18
helper: (event) ->
$('<div class="tire-icon"></div>').append($('<img src="/images/tyre_32_32.png" />'))
start: (event, ui) ->
if $(event.target).hasClass 'in-use'
$('.js-send-to-maintenance-box').addClass 'is-highlighted'
else
$('.ui-droppable').addClass 'is-highlighted'
stop: (event, ui) ->
$('.ui-droppable')
.removeClass 'is-highlighted'
.removeClass 'is-dragover'

This did the trick for me:
appendTo: 'body'
Like so:
$(this).draggable({
helper: "clone",
cursor: "move",
appendTo: 'body'
});

Related

Drag and Drop a variety of Elements in jsPlumb

I am working with jsPlumb and am trying to create a simple toolbox of 2 elements. These elements need to be dragged and dropped onto the canvas where further action such as creating connections in between them and deleting them can be performed. But for now, I've been able to accept 2 div under the droppable method. Depending on the accepted div, the class to be added and the fields to be appended to the element change. The working version of the following code: https://github.com/NayantaraJeyaraj/MultipleElements
$(".project").draggable
({
helper : 'clone',
cursor : 'pointer',
tolerance : 'fit',
revert : true
});
$(".query").draggable
({
helper : 'clone',
cursor : 'pointer',
tolerance : 'fit',
revert : true
});
And the droppable method:
$("#container").droppable
({
accept: '.project, .query',
containment: 'container',
drop: function (e, ui) {
droppedElement = ui.helper.clone();
ui.helper.remove();
$(droppedElement).removeAttr("class");
jsPlumb.repaint(ui.helper);
var newAgent = $('<div>').attr('id', 'pro' + i).addClass('pro');
newAgent.text('Element ' + i);
$(droppedElement).draggable({containment: "container"});
$('#container').append(newAgent);
jsPlumb.draggable(newAgent, {
containment: 'parent'
});
newAgent.dblclick(function(e) {
jsPlumb.detachAllConnections(newAgent.attr('id'));
jsPlumb.removeAllEndpoints($(this));
jsPlumb.detach($(this));
$(newAgent).remove();
});
i++;
}
});
What I need this piece of code to do is, to add the "pro" class to the newAgent( as shown in the code) when the accepted div is '.project' else if the accepted div is '.query' it needs to add the "que" class instead of the pro class. But here, currently it adds the pro class for both instances. How ca I detect which is being accepted and then add the class accordingly?
I worked a long with jsplumb for my project and i think you can take a look at this codepen :-
http://codepen.io/soniabhishek/pen/XjNYGp?editors=1010
//This is specific function when drop occurs
jsPlumb.draggable(c1_1,{
stop: function(params){
console.log("dropped", params)
}
});
Here i have some basic example of drag drop, multi select, as well as group concepts.
And in particular look for stop function which you particularly looking for.
Thanks.

Is there a way to lock/freeze a jquery datatable after it has been instantiated?

I'm looking for a way to toggle the scrolling of a datatable when using a draggable link ala jqueryUI.
Due to space constraints I need a scrolling DataTable and due to UI requirements I need draggable links.
Example I fleshed out: http://jsfiddle.net/sqwgs6wb/8/
JavaScript from the sample:
$(document).ready( function () {
var table = $('#example').DataTable({
"scrollX": true,
"scrollCollapse": true,
"bJQueryUI": true,
"scrollY": 140 });
$( init1 );
$( init2 );
$( ".makeMeDraggable" ).on( "drag", function( event, ui ) {
$('#status').html("dragging");
} );
$( ".makeMeDraggable" ).on( "dragstop", function( event, ui ) {
$('#status').html("Stopped dragging");
} );
} );
function init1() {
$('.makeMeDraggable').each(function(i) {
$(this).draggable({
revert: true,
delay: 100,
helper: "clone",
containment: "document"});
})}
function init2() {
$('#makeMeDroppable').droppable( {
drop: handleDropEvent
} );
}
function handleDropEvent( event, ui ) {
var draggable = ui.draggable;
alert( 'A Link was dropped onto me! with a URL of: ' + draggable.attr('href') );
}
Using jqueryUI I can detect when a datatable item(link) is being dragged and when it is done being dragged but the problem I'm running into is that the contents of the table shift around when I want to drag a link onto a drop area. Thus losing their place in the table.
I've looked on Stack and on datatables.net and I think it might be possible to access an extended function and freeze it but I'm not sure about how to do that.
I would very much like the contents of the table to not move when a user drags a draggable item from the datatable. Basically, freezing the table scroll in the X and Y axis would rock and naturally I would need the ability to unfreeze it.
I found a post that had a similar problem and verified that the solution fixes your problem in the fiddle. Here is the thread that discusses it
Draggable element hidden outside container
Basically, these 3 options need to be setup on your draggble setup
helper: 'clone',
revert: 'invalid',
appendTo: 'body'
Here is a working update of the fiddle with these options
http://jsfiddle.net/sqwgs6wb/11/
It's a JqueryUI issue, or rather my lack of knowledge of all the options.
The answer is to add appendTo to the jqueryUI Draggable initialization.
http://jsfiddle.net/sqwgs6wb/9/
function init1() {
$('.makeMeDraggable').each(function(i) {
$(this).draggable({
revert: true,
delay: 100,
helper: "clone",
appendTo: 'body', //<-==This is what fixed it.
containment: "document"});
})}
The appendTo 'body' option causes the draggable item to be created at the body level and not inside the scrollable container like it was before.

Set Jquery Draggable text's top and left on mouse move?

A custom grid whose items are draggable i.e. you can drag any row and drop it to the left tree structure.What i did for drggable is this
$("#ulMyItemsNew").append(liItem).find("li").draggable({
helper: 'clone',
revert: function (event) {
//hides tooltip when not a valid drop
$(".tooltipProduct:visible").hide();
return !event;
},
cursor: 'move',
start: function (event, ui) {
$(this).draggable("option", "cursorAt", {
left: event.pageX,
top: event.pageY
});
},
zIndex: 507000
});
Actually the thing is when i start dragging any row from Manufacturer then my mouse and the dragging text moves together.But when i start dragging from Model Number then my mouse and the dragging text gets distance.And when i start dragging from Description then my mouse and the dragging text gets more distance.What i want is , whether i drag from Manufacturer or Model Number or Description ,the dragging text should always move alongwith my mouse.There should be no distance in between them .
I know in the code area
start: function (event, ui) {
$(this).draggable("option", "cursorAt", {
left: event.pageX,
top: event.pageY
});
}
i am doing event.pageX and event.pageY and the event is not the mouse move event rather it is the draggable text event.I did called a function also inside the "start" helper like this
start: function (event, ui) {
GetMousePosition();
}
function GetMousePosition() {
$("#ulMyItemsNew li.ui-draggable-dragging").mousemove(function (event) {
var offset = $("#ulMyItemsNew li.ui-draggable-dragging").offset();
$("#ulMyItemsNew li.ui-draggable-dragging").css({ left: event.pageX - offset.left, top: event.pageX - offset.top });
});
}
But nothing works as i want ulMyItemsNew is the ul id under which all the li rows of the grid are present. li.ui-draggable-dragging is the class of that draggable text that gets appended dynamically at the bottom of ul .
Any help would be much appreciated . I am stuck in this from 2 weeks . Thanks in Advance !!
Here is the Snap Shot -
I think you have fixed the cursor position when you start dragging:
$(this).draggable("option", "cursorAt", {
left: event.pageX,
top: event.pageY
});
Thats why it is happening.
Using this-
cursorAt: { left: 1, top:1 }
option to specify another location relative to the draggable (specify a pixel value from the top, right, bottom, and/or left). Customize the cursor's appearance by supplying the cursor option with a valid CSS cursor value: default, move, pointer, crosshair, etc.
Check here for more detail
draggable - cursor-style
I did this and it worked as i wanted .Now my cursor and the draggable "li" moves together.I didn't knew that the cursorAt helper actually sets the cursor top and left with respect to the draggable item.
$("#ulDragNew").append(liItem).find("li").draggable({
helper: 'clone',
cursorAt: {
left: 40,
top: 20
},
revert: function (event) {
//hides tooltip when not a valid drop
$(".tooltipProduct:visible").hide();
return !event;
},
cursor: 'move',
zIndex: 100
});
}

Maintaining js while appending elements

I'm not super experienced and was hoping someone could give me some tips.
I'm trying to create a system where images can be transferred from a holding container to a manipulative container where they can be re-sized and dragged.
I have a manipulative here: Fiddle Demo
And am trying to get the "click in/double-click out" system to work here: Fiddle Demo
<div class="frame"></div>
<div class="inventory">
<images>
</div>
$(".frame img")
.draggable({
containment: "parent",
cursor: "move"
}).resizable({
aspectRatio:1,
containment: "parent",
minHeight: 50,
minWidth: 50
});
$('.inventory img').click(function(){
$(this).appendTo(".frame");
});
$('.frame img').dblclick(function(){
$(this).appendTo(".inventory");
$(this).removeClass('added');
});
The main problem I believe is that once I append the divs, the js doesn't refresh and apply based on the arrangements of elements.
Any help would be greatly appreciated!
Thank you!
Since the evaluation of the selectors need to be dynamic you need to use event delegation
$('.inventory').on('click', 'img', function () {
$(this).appendTo(".frame");
});
$('.frame').on('dblclick', 'img', function () {
$(this).appendTo(".inventory");
$(this).removeClass('added');
});
Demo: Fiddle
Note: This will not handle the resizable/draggable behaviors - you will need to manually destroy/add this behaviors when you move the element from one container to another one
I updated Arun P Johny's fiddle: http://jsfiddle.net/u4xKW/2/.
$(".frame img")
.draggable({
containment: "parent",
cursor: "move"
}).resizable({
aspectRatio: 1,
containment: "parent",
minHeight: 50,
minWidth: 50
});
$('.inventory').on('click', 'img', function () {
$(this).resizable({
aspectRatio: 1,
containment: "parent",
minHeight: 50,
minWidth: 50
});
$(this).parent().appendTo(".frame").draggable({
containment: "parent",
cursor: "move"
});
});
$('.frame').on('dblclick', '.ui-draggable', function () {
$(this).appendTo(".inventory");
$(this).draggable("destroy");
$("img", this).resizable("destroy");
});
This adds and removes the draggable and resizable functions from the items when they are added and removed.

Drag drop and calculating width

I want to calculate and select drop area in my drag&drop application.
What I want to make:
When i drag box to top or bottom of the droppable div, width must be 100%
When i drag box to near the other box, (if one box in a row) their widths must be 50% - 50%
If a drag box and change place which box is already in wrapper, they must be calculated like that again.
Here is my example code
$(".box").draggable({
snap: '#droppable',
snapMode: 'outer',
revert: "invalid",
cursor: "move",
helper: "clone"
//connectToSortable: "#droppable"
});
$("#wrapper").droppable({
drop: function(event, ui) {
var dropped = $(ui.draggable).clone();
var droppedOn = $(this);
$(dropped).detach().css({
top: 0,
left: 0
}).appendTo(droppedOn);
$(this).addClass("ui-state.highlight").find("p").html("");
}
});
Can you please tell me the way how can I do that?
Thanks
Take a look at this JQFAQ.com topic, this will help you to set the calculated width and we can drop the elements in specified area. There are few more sample FAQs too.

Categories

Resources