Is it possible to specify jQuery UI position, where X coordinate is relative to element1 and Y coordinate is relative to element2?
Example 1: I want to pop-up a dialog, so that it is centered horizontally, but vertically it is centered on some other element.
Example 2: I have two items in my DOM, and I want to postion the third in the outer corner of these two. I know I can pick the position of each of them, and use x from one and y from the other, but it would look so much nicer to do something like
jQuery('#UpperRight').postion({
my : 'right top',
at : 'right',
of : '#rightMostItem',
at : 'top',
of : '#topMostItem'
}) // double parameters don't work of course
or
jQuery('#UpperRight').position({
my : 'right IGNORE',
at : 'right IGNORE',
of : '#rightMostItem'})
.postion({
my : 'IGNORE top',
at : 'IGNORE top',
of : '#topMostItem'
}); // where IGNORE overrides the default center
All attempts so far have been trapped with 'center' being the default, not allowed to use 'my current position in one direction' as basis. Any good ideas are very welle!
Is it possible to specify jQuery UI position, where X coordinate is relative to element1 and Y coordinate is relative to element2?
Example 1: I want to pop-up a dialog, so that it is centered horizontally, but vertically it is centered on some other element.
Example 2: I have two items in my DOM, and I want to postion the third in the outer corner of these two. I know I can pick the position of each of them, and use x from one and y from the other, but it would look so much nicer to do something like
jQuery('#UpperRight').postion({
my : 'right top',
at : 'right',
of : '#rightMostItem',
at : 'top',
of : '#topMostItem'
}) // double parameters don't work of course
or
jQuery('#UpperRight').position({
my : 'right IGNORE',
at : 'right IGNORE',
of : '#rightMostItem'})
.postion({
my : 'IGNORE top',
at : 'IGNORE top',
of : '#topMostItem'
}); // where IGNORE overrides the default center
All attempts so far have been trapped with 'center' being the default, not allowed to use 'my current position in one direction' as basis. Any good ideas are very welle!
Share Improve this question edited Apr 28, 2015 at 8:11 Salman Arshad 272k84 gold badges443 silver badges534 bronze badges asked Jun 23, 2013 at 21:01 FtLieFtLie 7734 silver badges14 bronze badges 2- Could you show an example fiddle ? Hard to understand what you try to position and how without some visuals. – rusln Commented Jun 25, 2013 at 14:35
- 1 +1 This is a great question! I have the same problem. I tried to generalize it a bit so that it gets more attention! PS: the IGNORE idea is exactly what I was thinking about! It would be great if there was such a solution. – Tomas Commented Apr 7, 2014 at 20:46
3 Answers
Reset to default 5 +50This is a quick jquery plugin that does what you want if i understand your question correctly.
http://jsfiddle/S4N5g/5/
plugin code:
$.fn.positionRelative = function(config) {
var element = this;
var config = config || {};
var x = config.x || false;
var y = config.y || false;
var of = config.of || false;
var css = {}, positionX, positionY;
if (x !== false) {
var offsetX = of.offset().left;
if (x === 'left') {
positionX = offsetX;
} else if(x === 'center') {
var elWidth = element.width();
var elOffsetWidth = elWidth / 2;
positionX = offsetX + (of.width() / 2);
positionX = positionX - elOffsetWidth;
} else if(x === 'right') {
positionX = offsetX + of.width();
}
css['left'] = positionX + 'px';
}
if (y !== false) {
var offsetY = of.offset().top;
if (y === 'top') {
positionY = offsetY;
} else if(y === 'center') {
var elHeight = element.height();
var elOffsetHeight = elHeight / 2;
positionY = offsetY + (of.height() / 2);
positionY = positionY - elOffsetHeight;
} else if(y === 'bottom') {
positionY = offsetY + of.height();
}
css['top'] = positionY + 'px';
}
css['position'] = 'absolute';
element.css(css);
return this;
}
Usage:
//Usage
$('.popup').positionRelative({
x: 'center',
of: $('.element1')
}).positionRelative({
y: 'center',
of: $('.element2')
});
You can also use the options left
, right
or center
for x
and top
, bottom
, center
for y
.
Regarding the revised question:
Is it possible to specify jQuery UI position, where X coordinate is relative to element1 and Y coordinate is relative to element2?
It is possible to achieve the desired results manually using .offset()
, .outerWidth()
and .css()
functions as follows:
It is pretty straightforward to grab the x and y coordinates of reference elements using offset function
You can then calculate the horizontal center, vertical center, right and bottom coordinates of reference elements by adding width/height (see below)
Once you have the reference coordinates, align the target element with these coordinates (see below)
Remaining coordinates of reference element given its left, top, width and height:
horizontal center = left + width / 2
vertical center = top + height / 2
right = left + width
bottom = top + height
Align target element corners with given x and y coordinates using CSS:
align left with x => left: x
align top with y => top: y
align right with x => left: x - width
align bottom with y => top: y - height
align horizontal center with x => left: x - width / 2
align vertical center with y => top: y - height / 2
Here is example code that aligns horizontal center/vertical center of an element with horizontal center of element 1 and vertical center of element 2:
var x1 = $("#div-1").offset().left + Math.floor($("#div-1").outerWidth() / 2);
var y1 = $("#div-2").offset().top + Math.floor($("#div-2").outerHeight() / 2);
var x2 = x1 - Math.floor($("#dialog").outerWidth() / 2);
var y2 = y1 - Math.floor($("#dialog").outerHeight() / 2);
$("#dialog").css({
left: x2,
top: y2
});
And here is the demo.
Given the above information, it is possible to write a generic function of your own.
Your requirements are very specific to this unique situation.
I don't have a ready-to-use solution for you, but a suggestion how to tackle the problem.
My suggestion is to implement a custom jQuery function (for example position2
) that will calculate the position according to your desired options.
Since jQuery UI code is available for everyone to browse through (and grab), you can look at the position
function implementation and copy most of the code to your new jQuery function.
Important! You can't use same property name in the options
object.
The usage of this new function will look something like that:
$("#element").position2({
my: "right top",
atX: "right",
ofX: "#rightMostItem",
atY: "top",
ofY: "#topMostItem"
});
I know that this solution is not the easiest, but I doubt if there's something built already that tackles your requirements.
Oh... and if you choose to implement it, don't forget to post your code here for others to use.