source: trunk/template-common/lib/ui/ui.dialog.js @ 3282

Last change on this file since 3282 was 3282, checked in by plg, 15 years ago

change: according to topic:15067, svn:keywords property was removed

  • Property svn:eol-style set to LF
File size: 13.5 KB
Line 
1/*
2 * jQuery UI Dialog
3 *
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.
7 *
8 * http://docs.jquery.com/UI/Dialog
9 *
10 * Depends:
11 *      ui.core.js
12 *      ui.draggable.js
13 *      ui.resizable.js
14 */
15(function($) {
16
17var setDataSwitch = {
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"
28};
29
30$.widget("ui.dialog", {
31        init: function() {
32                var self = this,
33                        options = this.options,
34                        resizeHandles = typeof options.resizable == 'string'
35                                ? options.resizable
36                                : 'n,e,s,w,se,sw,ne,nw',
37                       
38                        uiDialogContent = this.element
39                                .addClass('ui-dialog-content')
40                                .wrap('<div/>')
41                                .wrap('<div/>'),
42                       
43                        uiDialogContainer = (this.uiDialogContainer = uiDialogContent.parent()
44                                .addClass('ui-dialog-container')
45                                .css({position: 'relative', width: '100%', height: '100%'})),
46                       
47                        title = options.title || uiDialogContent.attr('title') || '',
48                        uiDialogTitlebar = (this.uiDialogTitlebar =
49                                $('<div class="ui-dialog-titlebar"/>'))
50                                .append('<span class="ui-dialog-title">' + title + '</span>')
51                                .append('<a href="#" class="ui-dialog-titlebar-close"><span>X</span></a>')
52                                .prependTo(uiDialogContainer),
53                       
54                        uiDialog = (this.uiDialog = uiDialogContainer.parent())
55                                .appendTo(document.body)
56                                .hide()
57                                .addClass('ui-dialog')
58                                .addClass(options.dialogClass)
59                                // add content classes to dialog
60                                // to inherit theme at top level of element
61                                .addClass(uiDialogContent.attr('className'))
62                                        .removeClass('ui-dialog-content')
63                                .css({
64                                        position: 'absolute',
65                                        width: options.width,
66                                        height: options.height,
67                                        overflow: 'hidden',
68                                        zIndex: options.zIndex
69                                })
70                                // setting tabIndex makes the div focusable
71                                // setting outline to 0 prevents a border on focus in Mozilla
72                                .attr('tabIndex', -1).css('outline', 0).keydown(function(ev) {
73                                        if (options.closeOnEscape) {
74                                                var ESC = 27;
75                                                (ev.keyCode && ev.keyCode == ESC && self.close());
76                                        }
77                                })
78                                .mousedown(function() {
79                                        self.moveToTop();
80                                }),
81                       
82                        uiDialogButtonPane = (this.uiDialogButtonPane = $('<div/>'))
83                                .addClass('ui-dialog-buttonpane').css({ position: 'absolute', bottom: 0 })
84                                .appendTo(uiDialog);
85               
86                this.uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar)
87                        .hover(
88                                function() {
89                                        $(this).addClass('ui-dialog-titlebar-close-hover');
90                                },
91                                function() {
92                                        $(this).removeClass('ui-dialog-titlebar-close-hover');
93                                }
94                        )
95                        .mousedown(function(ev) {
96                                ev.stopPropagation();
97                        })
98                        .click(function() {
99                                self.close();
100                                return false;
101                        });
102
103                this.uiDialogTitlebar.find("*").add(this.uiDialogTitlebar).each(function() {
104                        $.ui.disableSelection(this);
105                });
106
107                if ($.fn.draggable) {
108                        uiDialog.draggable({
109                                cancel: '.ui-dialog-content',
110                                helper: options.dragHelper,
111                                handle: '.ui-dialog-titlebar',
112                                start: function(e, ui) {
113                                        self.moveToTop();
114                                        (options.dragStart && options.dragStart.apply(self.element[0], arguments));
115                                },
116                                drag: function(e, ui) {
117                                        (options.drag && options.drag.apply(self.element[0], arguments));
118                                },
119                                stop: function(e, ui) {
120                                        (options.dragStop && options.dragStop.apply(self.element[0], arguments));
121                                        $.ui.dialog.overlay.resize();
122                                }
123                        });
124                        (options.draggable || uiDialog.draggable('disable'));
125                }
126               
127                if ($.fn.resizable) {
128                        uiDialog.resizable({
129                                cancel: '.ui-dialog-content',
130                                helper: options.resizeHelper,
131                                maxWidth: options.maxWidth,
132                                maxHeight: options.maxHeight,
133                                minWidth: options.minWidth,
134                                minHeight: options.minHeight,
135                                start: function() {
136                                        (options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
137                                },
138                                resize: function(e, ui) {
139                                        (options.autoResize && self.size.apply(self));
140                                        (options.resize && options.resize.apply(self.element[0], arguments));
141                                },
142                                handles: resizeHandles,
143                                stop: function(e, ui) {
144                                        (options.autoResize && self.size.apply(self));
145                                        (options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
146                                        $.ui.dialog.overlay.resize();
147                                }
148                        });
149                        (options.resizable || uiDialog.resizable('disable'));
150                }
151               
152                this.createButtons(options.buttons);
153                this.isOpen = false;
154               
155                (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
156                (options.autoOpen && this.open());
157        },
158       
159        setData: function(key, value){
160                (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
161                switch (key) {
162                        case "buttons":
163                                this.createButtons(value);
164                                break;
165                        case "draggable":
166                                this.uiDialog.draggable(value ? 'enable' : 'disable');
167                                break;
168                        case "height":
169                                this.uiDialog.height(value);
170                                break;
171                        case "position":
172                                this.position(value);
173                                break;
174                        case "resizable":
175                                (typeof value == 'string' && this.uiDialog.data('handles.resizable', value));
176                                this.uiDialog.resizable(value ? 'enable' : 'disable');
177                                break;
178                        case "title":
179                                $(".ui-dialog-title", this.uiDialogTitlebar).text(value);
180                                break;
181                        case "width":
182                                this.uiDialog.width(value);
183                                break;
184                }
185               
186                $.widget.prototype.setData.apply(this, arguments);
187        },
188       
189        position: function(pos) {
190                var wnd = $(window), doc = $(document),
191                        pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
192                        minTop = pTop;
193               
194                if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
195                        pos = [
196                                pos == 'right' || pos == 'left' ? pos : 'center',
197                                pos == 'top' || pos == 'bottom' ? pos : 'middle'
198                        ];
199                }
200                if (pos.constructor != Array) {
201                        pos = ['center', 'middle'];
202                }
203                if (pos[0].constructor == Number) {
204                        pLeft += pos[0];
205                } else {
206                        switch (pos[0]) {
207                                case 'left':
208                                        pLeft += 0;
209                                        break;
210                                case 'right':
211                                        pLeft += wnd.width() - this.uiDialog.width();
212                                        break;
213                                default:
214                                case 'center':
215                                        pLeft += (wnd.width() - this.uiDialog.width()) / 2;
216                        }
217                }
218                if (pos[1].constructor == Number) {
219                        pTop += pos[1];
220                } else {
221                        switch (pos[1]) {
222                                case 'top':
223                                        pTop += 0;
224                                        break;
225                                case 'bottom':
226                                        pTop += wnd.height() - this.uiDialog.height();
227                                        break;
228                                default:
229                                case 'middle':
230                                        pTop += (wnd.height() - this.uiDialog.height()) / 2;
231                        }
232                }
233               
234                // prevent the dialog from being too high (make sure the titlebar
235                // is accessible)
236                pTop = Math.max(pTop, minTop);
237                this.uiDialog.css({top: pTop, left: pLeft});
238        },
239
240        size: function() {
241                var container = this.uiDialogContainer,
242                        titlebar = this.uiDialogTitlebar,
243                        content = this.element,
244                        tbMargin = parseInt(content.css('margin-top'),10) + parseInt(content.css('margin-bottom'),10),
245                        lrMargin = parseInt(content.css('margin-left'),10) + parseInt(content.css('margin-right'),10);
246                content.height(container.height() - titlebar.outerHeight() - tbMargin);
247                content.width(container.width() - lrMargin);
248        },
249       
250        open: function() {
251                if (this.isOpen) { return; }
252               
253                this.overlay = this.options.modal ? new $.ui.dialog.overlay(this) : null;
254                (this.uiDialog.next().length > 0) && this.uiDialog.appendTo('body');
255                this.position(this.options.position);
256                this.uiDialog.show(this.options.show);
257                this.options.autoResize && this.size();
258                this.moveToTop(true);
259               
260                // CALLBACK: open
261                var openEV = null;
262                var openUI = {
263                        options: this.options
264                };
265                this.uiDialogTitlebarClose.focus();
266                this.element.triggerHandler("dialogopen", [openEV, openUI], this.options.open);
267               
268                this.isOpen = true;
269        },
270       
271        // the force parameter allows us to move modal dialogs to their correct
272        // position on open
273        moveToTop: function(force) {
274                if ((this.options.modal && !force)
275                        || (!this.options.stack && !this.options.modal)) { return this.element.triggerHandler("dialogfocus", [null, { options: this.options }], this.options.focus); }
276               
277                var maxZ = this.options.zIndex, options = this.options;
278                $('.ui-dialog:visible').each(function() {
279                        maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
280                });
281                (this.overlay && this.overlay.$el.css('z-index', ++maxZ));
282                this.uiDialog.css('z-index', ++maxZ);
283               
284                this.element.triggerHandler("dialogfocus", [null, { options: this.options }], this.options.focus);
285        },
286       
287        close: function() {
288                (this.overlay && this.overlay.destroy());
289                this.uiDialog.hide(this.options.hide);
290
291                // CALLBACK: close
292                var closeEV = null;
293                var closeUI = {
294                        options: this.options
295                };
296                this.element.triggerHandler("dialogclose", [closeEV, closeUI], this.options.close);
297                $.ui.dialog.overlay.resize();
298               
299                this.isOpen = false;
300        },
301       
302        destroy: function() {
303                (this.overlay && this.overlay.destroy());
304                this.uiDialog.hide();
305                this.element
306                        .unbind('.dialog')
307                        .removeData('dialog')
308                        .removeClass('ui-dialog-content')
309                        .hide().appendTo('body');
310                this.uiDialog.remove();
311        },
312       
313        createButtons: function(buttons) {
314                var self = this,
315                        hasButtons = false,
316                        uiDialogButtonPane = this.uiDialogButtonPane;
317               
318                // remove any existing buttons
319                uiDialogButtonPane.empty().hide();
320               
321                $.each(buttons, function() { return !(hasButtons = true); });
322                if (hasButtons) {
323                        uiDialogButtonPane.show();
324                        $.each(buttons, function(name, fn) {
325                                $('<button/>')
326                                        .text(name)
327                                        .click(function() { fn.apply(self.element[0], arguments); })
328                                        .appendTo(uiDialogButtonPane);
329                        });
330                }
331        }
332});
333
334$.extend($.ui.dialog, {
335        defaults: {
336                autoOpen: true,
337                autoResize: true,
338                bgiframe: false,
339                buttons: {},
340                closeOnEscape: true,
341                draggable: true,
342                height: 200,
343                minHeight: 100,
344                minWidth: 150,
345                modal: false,
346                overlay: {},
347                position: 'center',
348                resizable: true,
349                stack: true,
350                width: 300,
351                zIndex: 1000
352        },
353       
354        overlay: function(dialog) {
355                this.$el = $.ui.dialog.overlay.create(dialog);
356        }
357});
358
359$.extend($.ui.dialog.overlay, {
360        instances: [],
361        events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
362                function(e) { return e + '.dialog-overlay'; }).join(' '),
363        create: function(dialog) {
364                if (this.instances.length === 0) {
365                        // prevent use of anchors and inputs
366                        // we use a setTimeout in case the overlay is created from an
367                        // event that we're going to be cancelling (see #2804)
368                        setTimeout(function() {
369                                $('a, :input').bind($.ui.dialog.overlay.events, function() {
370                                        // allow use of the element if inside a dialog and
371                                        // - there are no modal dialogs
372                                        // - there are modal dialogs, but we are in front of the topmost modal
373                                        var allow = false;
374                                        var $dialog = $(this).parents('.ui-dialog');
375                                        if ($dialog.length) {
376                                                var $overlays = $('.ui-dialog-overlay');
377                                                if ($overlays.length) {
378                                                        var maxZ = parseInt($overlays.css('z-index'), 10);
379                                                        $overlays.each(function() {
380                                                                maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
381                                                        });
382                                                        allow = parseInt($dialog.css('z-index'), 10) > maxZ;
383                                                } else {
384                                                        allow = true;
385                                                }
386                                        }
387                                        return allow;
388                                });
389                        }, 1);
390                       
391                        // allow closing by pressing the escape key
392                        $(document).bind('keydown.dialog-overlay', function(e) {
393                                var ESC = 27;
394                                (e.keyCode && e.keyCode == ESC && dialog.close()); 
395                        });
396                       
397                        // handle window resize
398                        $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
399                }
400               
401                var $el = $('<div/>').appendTo(document.body)
402                        .addClass('ui-dialog-overlay').css($.extend({
403                                borderWidth: 0, margin: 0, padding: 0,
404                                position: 'absolute', top: 0, left: 0,
405                                width: this.width(),
406                                height: this.height()
407                        }, dialog.options.overlay));
408               
409                (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
410               
411                this.instances.push($el);
412                return $el;
413        },
414       
415        destroy: function($el) {
416                this.instances.splice($.inArray(this.instances, $el), 1);
417               
418                if (this.instances.length === 0) {
419                        $('a, :input').add([document, window]).unbind('.dialog-overlay');
420                }
421               
422                $el.remove();
423        },
424       
425        height: function() {
426                if ($.browser.msie && $.browser.version < 7) {
427                        var scrollHeight = Math.max(
428                                document.documentElement.scrollHeight,
429                                document.body.scrollHeight
430                        );
431                        var offsetHeight = Math.max(
432                                document.documentElement.offsetHeight,
433                                document.body.offsetHeight
434                        );
435                       
436                        if (scrollHeight < offsetHeight) {
437                                return $(window).height() + 'px';
438                        } else {
439                                return scrollHeight + 'px';
440                        }
441                } else {
442                        return $(document).height() + 'px';
443                }
444        },
445       
446        width: function() {
447                if ($.browser.msie && $.browser.version < 7) {
448                        var scrollWidth = Math.max(
449                                document.documentElement.scrollWidth,
450                                document.body.scrollWidth
451                        );
452                        var offsetWidth = Math.max(
453                                document.documentElement.offsetWidth,
454                                document.body.offsetWidth
455                        );
456                       
457                        if (scrollWidth < offsetWidth) {
458                                return $(window).width() + 'px';
459                        } else {
460                                return scrollWidth + 'px';
461                        }
462                } else {
463                        return $(document).width() + 'px';
464                }
465        },
466       
467        resize: function() {
468                /* If the dialog is draggable and the user drags it past the
469                 * right edge of the window, the document becomes wider so we
470                 * need to stretch the overlay. If the user then drags the
471                 * dialog back to the left, the document will become narrower,
472                 * so we need to shrink the overlay to the appropriate size.
473                 * This is handled by shrinking the overlay before setting it
474                 * to the full document size.
475                 */
476                var $overlays = $([]);
477                $.each($.ui.dialog.overlay.instances, function() {
478                        $overlays = $overlays.add(this);
479                });
480               
481                $overlays.css({
482                        width: 0,
483                        height: 0
484                }).css({
485                        width: $.ui.dialog.overlay.width(),
486                        height: $.ui.dialog.overlay.height()
487                });
488        }
489});
490
491$.extend($.ui.dialog.overlay.prototype, {
492        destroy: function() {
493                $.ui.dialog.overlay.destroy(this.$el);
494        }
495});
496
497})(jQuery);
Note: See TracBrowser for help on using the repository browser.