2
* jQuery UI Dialog @VERSION
4
* Copyright (c) 2008 Richard D. Worth (rdworth.org)
5
* Dual licensed under the MIT (MIT-LICENSE.txt)
6
* and GPL (GPL-LICENSE.txt) licenses.
8
* http://docs.jquery.com/UI/Dialog
18
dragStart: "start.draggable",
19
drag: "drag.draggable",
20
dragStop: "stop.draggable",
21
maxHeight: "maxHeight.resizable",
22
minHeight: "minHeight.resizable",
23
maxWidth: "maxWidth.resizable",
24
minWidth: "minWidth.resizable",
25
resizeStart: "start.resizable",
26
resize: "drag.resizable",
27
resizeStop: "stop.resizable"
30
$.widget("ui.dialog", {
32
this.originalTitle = this.element.attr('title');
33
this.options.title = this.options.title || this.originalTitle;
36
options = this.options,
38
uiDialogContent = this.element
40
.addClass('ui-dialog-content')
44
uiDialogContainer = (this.uiDialogContainer = uiDialogContent.parent())
45
.addClass('ui-dialog-container')
52
uiDialogTitlebar = (this.uiDialogTitlebar = $('<div/>'))
53
.addClass('ui-dialog-titlebar')
54
.append('<a href="#" class="ui-dialog-titlebar-close"><span>X</span></a>')
55
.prependTo(uiDialogContainer),
57
title = options.title || ' ',
58
titleId = $.ui.dialog.getTitleId(this.element),
59
uiDialogTitle = $('<span/>')
60
.addClass('ui-dialog-title')
63
.prependTo(uiDialogTitlebar),
65
uiDialog = (this.uiDialog = uiDialogContainer.parent())
66
.appendTo(document.body)
68
.addClass('ui-dialog')
69
.addClass(options.dialogClass)
70
// add content classes to dialog
71
// to inherit theme at top level of element
72
.addClass(uiDialogContent.attr('className'))
73
.removeClass('ui-dialog-content')
77
height: options.height,
79
zIndex: options.zIndex
81
// setting tabIndex makes the div focusable
82
// setting outline to 0 prevents a border on focus in Mozilla
83
.attr('tabIndex', -1).css('outline', 0).keydown(function(ev) {
84
(options.closeOnEscape && ev.keyCode
85
&& ev.keyCode == $.keyCode.ESCAPE && self.close());
87
.mousedown(function() {
91
uiDialogButtonPane = (this.uiDialogButtonPane = $('<div/>'))
92
.addClass('ui-dialog-buttonpane')
99
this.uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar)
102
$(this).addClass('ui-dialog-titlebar-close-hover');
105
$(this).removeClass('ui-dialog-titlebar-close-hover');
108
.mousedown(function(ev) {
109
ev.stopPropagation();
116
uiDialogTitlebar.find("*").add(uiDialogTitlebar).each(function() {
117
$.ui.disableSelection(this);
120
(options.draggable && $.fn.draggable && this._makeDraggable());
121
(options.resizable && $.fn.resizable && this._makeResizable());
123
this._createButtons(options.buttons);
124
this._isOpen = false;
126
(options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
127
(options.autoOpen && this.open());
130
destroy: function() {
131
(this.overlay && this.overlay.destroy());
132
this.uiDialog.hide();
135
.removeData('dialog')
136
.removeClass('ui-dialog-content')
137
.hide().appendTo('body');
138
this.uiDialog.remove();
140
(this.originalTitle && this.element.attr('title', this.originalTitle));
144
if (false === this._trigger('beforeclose', null, { options: this.options })) {
148
(this.overlay && this.overlay.destroy());
150
.hide(this.options.hide)
151
.unbind('keypress.ui-dialog');
153
this._trigger('close', null, { options: this.options });
154
$.ui.dialog.overlay.resize();
156
this._isOpen = false;
164
if (this._isOpen) { return; }
166
this.overlay = this.options.modal ? new $.ui.dialog.overlay(this) : null;
167
(this.uiDialog.next().length && this.uiDialog.appendTo('body'));
168
this._position(this.options.position);
169
this.uiDialog.show(this.options.show);
170
(this.options.autoResize && this._size());
171
this._moveToTop(true);
173
// prevent tabbing out of modal dialogs
174
(this.options.modal && this.uiDialog.bind('keypress.ui-dialog', function(e) {
175
if (e.keyCode != $.keyCode.TAB) {
179
var tabbables = $(':tabbable', this),
180
first = tabbables.filter(':first')[0],
181
last = tabbables.filter(':last')[0];
183
if (e.target == last && !e.shiftKey) {
184
setTimeout(function() {
187
} else if (e.target == first && e.shiftKey) {
188
setTimeout(function() {
194
this.uiDialog.find(':tabbable:first').focus();
195
this._trigger('open', null, { options: this.options });
199
_createButtons: function(buttons) {
202
uiDialogButtonPane = this.uiDialogButtonPane;
204
// remove any existing buttons
205
uiDialogButtonPane.empty().hide();
207
$.each(buttons, function() { return !(hasButtons = true); });
209
uiDialogButtonPane.show();
210
$.each(buttons, function(name, fn) {
211
$('<button type="button"></button>')
213
.click(function() { fn.apply(self.element[0], arguments); })
214
.appendTo(uiDialogButtonPane);
219
_makeDraggable: function() {
221
options = this.options;
223
this.uiDialog.draggable({
224
cancel: '.ui-dialog-content',
225
helper: options.dragHelper,
226
handle: '.ui-dialog-titlebar',
229
(options.dragStart && options.dragStart.apply(self.element[0], arguments));
232
(options.drag && options.drag.apply(self.element[0], arguments));
235
(options.dragStop && options.dragStop.apply(self.element[0], arguments));
236
$.ui.dialog.overlay.resize();
241
_makeResizable: function(handles) {
242
handles = (handles === undefined ? this.options.resizable : handles);
244
options = this.options,
245
resizeHandles = typeof handles == 'string'
247
: 'n,e,s,w,se,sw,ne,nw';
249
this.uiDialog.resizable({
250
cancel: '.ui-dialog-content',
251
helper: options.resizeHelper,
252
maxWidth: options.maxWidth,
253
maxHeight: options.maxHeight,
254
minWidth: options.minWidth,
255
minHeight: options.minHeight,
257
(options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
260
(options.autoResize && self._size.apply(self));
261
(options.resize && options.resize.apply(self.element[0], arguments));
263
handles: resizeHandles,
265
(options.autoResize && self._size.apply(self));
266
(options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
267
$.ui.dialog.overlay.resize();
272
// the force parameter allows us to move modal dialogs to their correct
274
_moveToTop: function(force) {
276
if ((this.options.modal && !force)
277
|| (!this.options.stack && !this.options.modal)) {
278
return this._trigger('focus', null, { options: this.options });
281
var maxZ = this.options.zIndex, options = this.options;
282
$('.ui-dialog:visible').each(function() {
283
maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
285
(this.overlay && this.overlay.$el.css('z-index', ++maxZ));
286
this.uiDialog.css('z-index', ++maxZ);
288
this._trigger('focus', null, { options: this.options });
291
_position: function(pos) {
292
var wnd = $(window), doc = $(document),
293
pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
296
if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
298
pos == 'right' || pos == 'left' ? pos : 'center',
299
pos == 'top' || pos == 'bottom' ? pos : 'middle'
302
if (pos.constructor != Array) {
303
pos = ['center', 'middle'];
305
if (pos[0].constructor == Number) {
313
pLeft += wnd.width() - this.uiDialog.width();
317
pLeft += (wnd.width() - this.uiDialog.width()) / 2;
320
if (pos[1].constructor == Number) {
328
pTop += wnd.height() - this.uiDialog.height();
332
pTop += (wnd.height() - this.uiDialog.height()) / 2;
336
// prevent the dialog from being too high (make sure the titlebar
338
pTop = Math.max(pTop, minTop);
339
this.uiDialog.css({top: pTop, left: pLeft});
342
_setData: function(key, value){
343
(setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
346
this._createButtons(value);
350
? this._makeDraggable()
351
: this.uiDialog.draggable('destroy'));
354
this.uiDialog.height(value);
357
this._position(value);
360
var uiDialog = this.uiDialog,
361
isResizable = this.uiDialog.is(':data(resizable)');
363
// currently resizable, becoming non-resizable
364
(isResizable && !value && uiDialog.resizable('destroy'));
366
// currently resizable, changing handles
367
(isResizable && typeof value == 'string' &&
368
uiDialog.resizable('option', 'handles', value));
370
// currently non-resizable, becoming resizable
371
(isResizable || this._makeResizable(value));
375
$(".ui-dialog-title", this.uiDialogTitlebar).html(value || ' ');
378
this.uiDialog.width(value);
382
$.widget.prototype._setData.apply(this, arguments);
386
var container = this.uiDialogContainer,
387
titlebar = this.uiDialogTitlebar,
388
content = this.element,
389
tbMargin = (parseInt(content.css('margin-top'), 10) || 0)
390
+ (parseInt(content.css('margin-bottom'), 10) || 0),
391
lrMargin = (parseInt(content.css('margin-left'), 10) || 0)
392
+ (parseInt(content.css('margin-right'), 10) || 0);
393
content.height(container.height() - titlebar.outerHeight() - tbMargin);
394
content.width(container.width() - lrMargin);
398
$.extend($.ui.dialog, {
421
getTitleId: function($el) {
422
return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid);
425
overlay: function(dialog) {
426
this.$el = $.ui.dialog.overlay.create(dialog);
430
$.extend($.ui.dialog.overlay, {
432
events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
433
function(e) { return e + '.dialog-overlay'; }).join(' '),
434
create: function(dialog) {
435
if (this.instances.length === 0) {
436
// prevent use of anchors and inputs
437
// we use a setTimeout in case the overlay is created from an
438
// event that we're going to be cancelling (see #2804)
439
setTimeout(function() {
440
$('a, :input').bind($.ui.dialog.overlay.events, function() {
441
// allow use of the element if inside a dialog and
442
// - there are no modal dialogs
443
// - there are modal dialogs, but we are in front of the topmost modal
445
var $dialog = $(this).parents('.ui-dialog');
446
if ($dialog.length) {
447
var $overlays = $('.ui-dialog-overlay');
448
if ($overlays.length) {
449
var maxZ = parseInt($overlays.css('z-index'), 10);
450
$overlays.each(function() {
451
maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
453
allow = parseInt($dialog.css('z-index'), 10) > maxZ;
462
// allow closing by pressing the escape key
463
$(document).bind('keydown.dialog-overlay', function(e) {
464
(dialog.options.closeOnEscape && e.keyCode
465
&& e.keyCode == $.keyCode.ESCAPE && dialog.close());
468
// handle window resize
469
$(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
472
var $el = $('<div/>').appendTo(document.body)
473
.addClass('ui-dialog-overlay').css($.extend({
474
borderWidth: 0, margin: 0, padding: 0,
475
position: 'absolute', top: 0, left: 0,
477
height: this.height()
478
}, dialog.options.overlay));
480
(dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
482
this.instances.push($el);
486
destroy: function($el) {
487
this.instances.splice($.inArray(this.instances, $el), 1);
489
if (this.instances.length === 0) {
490
$('a, :input').add([document, window]).unbind('.dialog-overlay');
498
if ($.browser.msie && $.browser.version < 7) {
499
var scrollHeight = Math.max(
500
document.documentElement.scrollHeight,
501
document.body.scrollHeight
503
var offsetHeight = Math.max(
504
document.documentElement.offsetHeight,
505
document.body.offsetHeight
508
if (scrollHeight < offsetHeight) {
509
return $(window).height() + 'px';
511
return scrollHeight + 'px';
514
} else if ($.browser.opera) {
519
// handle "good" browsers
521
return $(document).height() + 'px';
527
if ($.browser.msie && $.browser.version < 7) {
528
var scrollWidth = Math.max(
529
document.documentElement.scrollWidth,
530
document.body.scrollWidth
532
var offsetWidth = Math.max(
533
document.documentElement.offsetWidth,
534
document.body.offsetWidth
537
if (scrollWidth < offsetWidth) {
538
return $(window).width() + 'px';
540
return scrollWidth + 'px';
543
} else if ($.browser.opera) {
548
// handle "good" browsers
550
return $(document).width() + 'px';
555
/* If the dialog is draggable and the user drags it past the
556
* right edge of the window, the document becomes wider so we
557
* need to stretch the overlay. If the user then drags the
558
* dialog back to the left, the document will become narrower,
559
* so we need to shrink the overlay to the appropriate size.
560
* This is handled by shrinking the overlay before setting it
561
* to the full document size.
563
var $overlays = $([]);
564
$.each($.ui.dialog.overlay.instances, function() {
565
$overlays = $overlays.add(this);
572
width: $.ui.dialog.overlay.width(),
573
height: $.ui.dialog.overlay.height()
578
$.extend($.ui.dialog.overlay.prototype, {
579
destroy: function() {
580
$.ui.dialog.overlay.destroy(this.$el);