I have 3x3 list of jQuery divs like so :
div1 div2 div3
div4 div5 div6
div7 div8 div9
When a div is dragged & dropped I would like to get its X & Y position in relation to the other div elements. so if div1 is dragged to div3 position I need to retrieve the postion 0,3 which represents the new position of div1. Do I need to use a plugin ?
So just to need to override droppable like so and get position :
$( ".myClass" ).droppable({ drop: function( event, ui )
{
alert('my position in relation to other divs is '+????
}
});
Ive added a jsFiddle : http://jsfiddle.net/aL3tr/
Can the X & Y co-ordinate of dropped item be retrieved ? In this case Y position will always be zero.
I forked your fiddle: http://jsfiddle.net/44R97/ to check the position within the #sortable-list:
stop: function() {
var myPos = $('#sortable').find('li.ui-draggable');
alert("I am at position "+($('#sortable').find('li').index(myPos)+1));
}
Note, that .index() counts from 0. Therefor I added 1 to the result...
add this to your draggable
stop: function(e,ui) {alert(ui.offset.top+","+ui.offset.left);}
(update)
ok, for all the siblings
$( "#sortable" ).sortable({
update: function(e,ui) {
console.log(ui.item.parent());
var i=ui.item;
ui.item.parent().children().each(
function (i,e) {
alert(ui.item.offset().top-$(e).offset().top);
}
);
},
revert: true
});
here obtaining X relative distance, Y is always 0 but you can obtain it in similar way
I updated your fiddle to show the coordinates of the clicked element with the following snippet:
$("li").click(function() {
alert("I am at (" + this.offsetLeft + "," + this.offsetTop + ").");
});
Related
I have tooltips set on top of an image. When the user clicks one of these tooltips a content opens to reveal some info.
I'd like to slide open the content up or down, depending where the tooltip is positioned (absolute). So, I'm trying to get the "top"-value and if it's larger than 50, add a class and sort out the rest with CSS.
The problem is I'm always just getting the "top"-value of the first element. Now I tried to add an each function, which leaves me with what seems to be the average value of all the tooltips' top positions?
$( ".tooltip" ).each(function() {
var toppos = $(".tooltip").css("top");
if ( parseInt(toppos) >= 50 ) {
$(this).addClass('higher');
}
});
I'm either using each wrong, or each is not what I should be going for here...
Target the current tooltip instead of all tooltips:
$( ".tooltip" ).each(function() {
var toppos = $(this).css("top");// Use $(this) instead of $('.tooltip')
if ( parseInt(toppos) >= 50 ) {
$(this).addClass('higher');
}
});
You may also try offset().top instead of css('top'):
var toppos = $(this).offset().top;
I am working on a project and I have an array of elements that are displayed one under each other.
When I press an arrow, I want to find the div closest to the bottom and scroll up to the top of that div.
This is what I have when I click the arrow:
$(".my-elements").each(function(i){
var divTopPosition = $(this).offset().top;
var scrollTop = $(window).scrollTop();
var difference = -Math.abs(scrollTop - divTopPosition);
if(/* this is the div closest to the bottom */)
{
$("body").animate({scrollTop: difference}, 2000);
return false;
}
});
if you know parent, you can use this selector:
$( "<parent>:last-child" )
I have a website with a draggable image inside a div, the script code looks like this:
var offset = 0,
xPos = 0,
yPos = 0;
$(document).ready(function(){
$(".item").draggable({
containment: '#house_wall1',
drag: function(){
offset = $(this).position();
xPos = offset.left;
yPos = offset.top;
$('#posX').text('x: ' + xPos);
$('#posY').text('y: ' + yPos);
},
// Find original position of dragged image.
start: function(event, ui) {
// Show start dragged position of image.
var Startpos = $(this).position();
$("div#start").text("START: \nLeft: "+ Startpos.left + "\nTop: " + Startpos.top);
},
// Find position where image is dropped.
stop: function(event, ui) {
// Show dropped position.
var Stoppos = $(this).position();
$("div#stop").text("STOP: \nLeft: "+ Stoppos.left + "\nTop: " + Stoppos.top);
}
});
});
My problem is that the x and y values are specified from the edge of the screen and not the div that they are supposed to. So if you have a screen with a lower resolution or if you make the browser window smaller then the x and y values will differ from a screen with a lower resolution.
I posted a problem similiar to this earlier and thought it was fixed, but unfortunatly it wasn't. I heard that using position() instead of offset() should do the job, but this still fix nothing. Maybe it's because the position() is equal to offset() in this case?
Thanks in advance.
if you want a div as coordinates origin for left and top. you have to set the position style property. div position="relative" or div position absolute
sorry, i forgot to mention that also the offset Properties are relative to the next parent which has positon: relative or absolute, if no parent has set the position property, the origin for IE is the client origin, what mozilla does is suspect for me, i hope they changed that soon to IE standard. you can see the difference by putting a border to the document.body and setting a div element to the document body and call alert (divid.offsetLeft); IE and mozilla will throw different values. Mozilla shows a value which only includes the body margin but not the border, and if you do a document.body.offset in mozilla it show a minus value????..... which is 0 in IE
exception are table inner Elements like td and tr , for them the table is the offsetParent
I am experiencing an issue with the jQuery-UI draggable and droppable. The issue that I'm facing is the fact that:
When I move an element from one div to another (during dragging using
.append() ) it shifts the element away from the mouse cursor
jarringly.
I know what causes it the left / top css positions are no longer correct since I'm moving from one relative div to another. But a fix for it I can't find.
I have tried quite a few "solutions" :
Changing the cursorAt position http://api.jqueryui.com/draggable/#option-cursorAt while dragging but this only goes in affect after mouseup and on the next mousedown.
Changing the css during dragging: http://api.jqueryui.com/draggable/#event-drag which while it works is not ideal since it has hiccups that make it flicker and move in random directions which is highly annoying.
Making the draggable div absolute instead of relative (Which locally in my backbone application so far has the 'best' results but is still far from desirable since i require the elements in the sidebar to be relative so they append nicely one below the other )
Here is my JSBin example of my issue.
JavaScript
var positionStack = [];
var fieldview = $('#field');
var sidebarView = $('#sidebar');
$('.draggable').draggable({
containment: ".container",
zIndex: 100,
cursorAt: {
top: 20,
left: 25
},
snap: '.sidebar',
snapMode: 'inner'
});
$('#field').droppable({
over: function(event, ui) {
dragOverElement({event: event, ui:ui});
}
});
$('#sidebar').droppable({
over: function(event, ui) {
dragOverElement({event: event, ui:ui});
}
});
function dragOverElement(data){
var me = this;
var lastItem = positionStack[positionStack -1];
if(lastItem !== data.event.target.id)
{
positionStack.push(data.event.target.id);
var player = $(data.ui.draggable);
var target = data.event.target.id;
switch(target)
{
case ('field'):
fieldview.append(player);
player.css('position', 'absolute');
break;
case ('sidebar'):
sidebarview.append(player);
player.css('position', 'absolute');
break;
}
}
}
I have 3 columns that are resizable. When one is made wider, the one to it's left is made smaller. Essentially there are only 2 handles. Left col and Mid col. So when Mid col is made thinner, Right col expands accordingly. All three of them are contained with a 900px parent div, so the sum of all three is always 900. They have max and min widths set statically.
My issue is that if you take the left handle and move it all the way to the right you're still able to use the right handle and expand the mid col past the edge of the parent div.
I thought of a way to solve that issue by writing up a function that checks the widths of the columns and then subtracts left and right columns from the parent div width, I called it mWid. This leaves me with the number I want to set as the maxWidth for Mid col.
Now the issue is that mWid is not gettings updated for here "maxWidth: mWid"
Here is what the function for the right handle looks like:
$(function() {
$("#midResizable").resizable({
handles: 'e',
containment: '#container',
maxWidth: mWid, // gets set once, but doesn't update! WHY?
minWidth: 195,
resize: function(event, ui) {
contWidth = $('#container').width()
newWidth = $(this).width()
leftWidth = $('#leftResizable').width()
rightWidth = $('#rightResizable').width()
$("#rightResizable").css("width", (contWidth-15)-(newWidth)-(leftWidth)+"px");
checkWid()
}
});
});
function checkWid() {
rightWidth = $('#rightResizable').width()
leftWidth = $('#leftResizable').width()
contWidth = $('#container').width()
mWid = (contWidth-15)-(rightWidth)-(leftWidth)
}
Check this out: http://jqueryui.com/demos/resizable/#option-maxWidth
Looks like maxWidth: mWid, only gets called on init.
The maxWidth needs to be explicitly set after that, like this:
$( "#midResizable" ).resizable( "option", "maxWidth", mWid );
you can use the below code in start method of resizable. It will update the maxWidth and maxHeight dynamically whenever you try to resize the div element.
$('.droppedBtn').resizable({
.... //you resizable properties
start: function(event,ui)
{
$( ".CLASSNAME" ).resizable( "option", "maxWidth", layout.lWidth);
$( ".CLASSNAME" ).resizable( "option", "maxHeight", layout.lHeight);
},
stop: function(event,ui){
}
});