Skip to content

Commit 6de9a53

Browse files
bhollisscottgonzalez
authored andcommitted
Dialog: allow setting position with ui.position arguments. Fixes #5459 - Dialog: expose .position() API
1 parent d8caa61 commit 6de9a53

File tree

2 files changed

+141
-48
lines changed

2 files changed

+141
-48
lines changed

tests/unit/dialog/dialog_options.js

+101-2
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,110 @@ test("position, default center on window", function() {
244244
var el = $('<div></div>').dialog();
245245
var offset = el.parent().offset();
246246
// use .position() instead to avoid replicating center-logic?
247-
same(offset.left, Math.floor($(window).width() / 2 - el.parent().width() / 2));
248-
same(offset.top, Math.floor($(window).height() / 2 - el.parent().height() / 2));
247+
same(offset.left, Math.floor($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft());
248+
same(offset.top, Math.floor($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop());
249249
el.remove();
250250
});
251251

252+
test("position, top on window", function() {
253+
var el = $('<div></div>').dialog({ position: "top" });
254+
var dialog = el.closest('.ui-dialog');
255+
var offset = dialog.offset();
256+
same(offset.left, Math.floor($(window).width() / 2 - dialog.outerWidth() / 2));
257+
same(offset.top, $(window).scrollTop());
258+
el.remove();
259+
});
260+
261+
test("position, left on window", function() {
262+
var el = $('<div></div>').dialog({ position: "left" });
263+
var dialog = el.closest('.ui-dialog');
264+
var offset = dialog.offset();
265+
same(offset.left, 0);
266+
same(offset.top, Math.floor($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop());
267+
el.remove();
268+
});
269+
270+
test("position, right bottom on window", function() {
271+
var el = $('<div></div>').dialog({ position: "right bottom" });
272+
var dialog = el.closest('.ui-dialog');
273+
var offset = dialog.offset();
274+
same(offset.left, $(window).width() - dialog.outerWidth());
275+
same(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop());
276+
el.remove();
277+
});
278+
279+
test("position, right bottom on window w/array", function() {
280+
var el = $('<div></div>').dialog({ position: ["right", "bottom"] });
281+
var dialog = el.closest('.ui-dialog');
282+
var offset = dialog.offset();
283+
same(offset.left, $(window).width() - dialog.outerWidth());
284+
same(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop());
285+
el.remove();
286+
});
287+
288+
test("position, offset from top left w/array", function() {
289+
var el = $('<div></div>').dialog({ position: [10, 10] });
290+
var dialog = el.closest('.ui-dialog');
291+
var offset = dialog.offset();
292+
same(offset.left, 10);
293+
same(offset.top, 10 + $(window).scrollTop());
294+
el.remove();
295+
});
296+
297+
test("position, right bottom at right bottom via ui.position args", function() {
298+
var el = $('<div></div>').dialog({
299+
position: {
300+
my: "right bottom",
301+
at: "right bottom"
302+
}
303+
});
304+
305+
var dialog = el.closest('.ui-dialog');
306+
var offset = dialog.offset();
307+
308+
same(offset.left, $(window).width() - dialog.outerWidth());
309+
same(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop());
310+
el.remove();
311+
});
312+
313+
test("position, at another element", function() {
314+
var parent = $('<div></div>').css({
315+
position: 'absolute',
316+
top: 400,
317+
left: 600,
318+
height: 10,
319+
width: 10
320+
});
321+
322+
var el = $('<div></div>').dialog({
323+
position: {
324+
my: "left top",
325+
at: "top left",
326+
of: parent
327+
}
328+
});
329+
330+
var dialog = el.closest('.ui-dialog');
331+
var offset = dialog.offset();
332+
var parentOffset = parent.offset();
333+
334+
same(offset.left, parentOffset.left);
335+
same(offset.top, parentOffset.top);
336+
337+
el.dialog('option', 'position', {
338+
my: "left top",
339+
at: "right bottom",
340+
of: parent
341+
});
342+
343+
same(offset.left, parentOffset.left + parent.outerWidth());
344+
same(offset.top, parentOffset.top + parent.outerHeight());
345+
346+
el.remove();
347+
parent.remove();
348+
});
349+
350+
252351
test("position, others", function() {
253352
ok(false, 'missing test - untested code is broken code');
254353
});

ui/jquery.ui.dialog.js

+40-46
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,19 @@ $.widget("ui.dialog", {
3939
minHeight: 150,
4040
minWidth: 150,
4141
modal: false,
42-
position: 'center',
42+
position: {
43+
my: 'center',
44+
at: 'center',
45+
of: window,
46+
collision: 'fit',
47+
// ensure that the titlebar is never outside the document
48+
using: function(pos) {
49+
var topOffset = $(this).css(pos).offset().top;
50+
if (topOffset < 0) {
51+
$(this).css('top', pos.top - topOffset);
52+
}
53+
}
54+
},
4355
resizable: true,
4456
show: null,
4557
stack: true,
@@ -449,45 +461,40 @@ $.widget("ui.dialog", {
449461
}
450462
},
451463

464+
452465
_position: function(position) {
453466
var myAt = [],
454467
offset = [0, 0],
455468
isVisible;
456469

457-
position = position || $.ui.dialog.prototype.options.position;
458-
459-
// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
460-
// if (typeof position == 'string' || $.isArray(position)) {
461-
// myAt = $.isArray(position) ? position : position.split(' ');
470+
if (position) {
471+
// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
472+
// if (typeof position == 'string' || $.isArray(position)) {
473+
// myAt = $.isArray(position) ? position : position.split(' ');
462474

463-
if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
464-
myAt = position.split ? position.split(' ') : [position[0], position[1]];
465-
if (myAt.length === 1) {
466-
myAt[1] = myAt[0];
467-
}
468-
469-
$.each(['left', 'top'], function(i, offsetPosition) {
470-
if (+myAt[i] === myAt[i]) {
471-
offset[i] = myAt[i];
472-
myAt[i] = offsetPosition;
475+
if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
476+
myAt = position.split ? position.split(' ') : [position[0], position[1]];
477+
if (myAt.length === 1) {
478+
myAt[1] = myAt[0];
473479
}
474-
});
475-
} else if (typeof position === 'object') {
476-
if ('left' in position) {
477-
myAt[0] = 'left';
478-
offset[0] = position.left;
479-
} else if ('right' in position) {
480-
myAt[0] = 'right';
481-
offset[0] = -position.right;
482-
}
483480

484-
if ('top' in position) {
485-
myAt[1] = 'top';
486-
offset[1] = position.top;
487-
} else if ('bottom' in position) {
488-
myAt[1] = 'bottom';
489-
offset[1] = -position.bottom;
490-
}
481+
$.each(['left', 'top'], function(i, offsetPosition) {
482+
if (+myAt[i] === myAt[i]) {
483+
offset[i] = myAt[i];
484+
myAt[i] = offsetPosition;
485+
}
486+
});
487+
488+
position = {
489+
my: myAt.join(" "),
490+
at: myAt.join(" "),
491+
offset: offset.join(" ")
492+
};
493+
}
494+
495+
position = $.extend({}, $.ui.dialog.prototype.options.position, position);
496+
} else {
497+
position = $.ui.dialog.prototype.options.position;
491498
}
492499

493500
// need to show the dialog to get the actual offset in the position plugin
@@ -498,20 +505,7 @@ $.widget("ui.dialog", {
498505
this.uiDialog
499506
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
500507
.css({ top: 0, left: 0 })
501-
.position({
502-
my: myAt.join(' '),
503-
at: myAt.join(' '),
504-
offset: offset.join(' '),
505-
of: window,
506-
collision: 'fit',
507-
// ensure that the titlebar is never outside the document
508-
using: function(pos) {
509-
var topOffset = $(this).css(pos).offset().top;
510-
if (topOffset < 0) {
511-
$(this).css('top', pos.top - topOffset);
512-
}
513-
}
514-
});
508+
.position(position);
515509
if (!isVisible) {
516510
this.uiDialog.hide();
517511
}

0 commit comments

Comments
 (0)