Posted By

MostThingsWeb on 10/18/10


Tagged


Versions (?)

dialogWrapper - version 1.6


 / Published in: JavaScript
 

URL: http://mosttw.wordpress.com/2010/10/16/dialogwrapper-version-1-6-released/

  1. /*
  2.  * Version 1.6
  3.  *
  4.  * http://mosttw.wordpress.com/
  5.  *
  6.  * Licensed under MIT License: http://en.wikipedia.org/wiki/MIT_License
  7.  *
  8.  * Copyright (c) 2010 MostThingsWeb
  9.  
  10.  Permission is hereby granted, free of charge, to any person obtaining a copy
  11.  of this software and associated documentation files (the "Software"), to deal
  12.  in the Software without restriction, including without limitation the rights
  13.  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14.  copies of the Software, and to permit persons to whom the Software is
  15.  furnished to do so, subject to the following conditions:
  16.  
  17.  The above copyright notice and this permission notice shall be included in
  18.  all copies or substantial portions of the Software.
  19.  
  20.  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21.  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22.  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23.  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24.  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25.  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26.  THE SOFTWARE.
  27.  
  28.  * Changelog:
  29.  *
  30.  * Version 1.6
  31.  * - Fixed overlay overflow issues in IE
  32.  * - Fixed overlay fadeIn in IE
  33.  *
  34.  *
  35.  * Version 1.5
  36.  * - Release
  37.  *
  38.  */
  39.  
  40. /*
  41.  *
  42.  * Portions of this software come from jQuery UI Dialog 1.8.4
  43.  * License (below):
  44.  *
  45.  * jQuery UI Dialog 1.8.4
  46.  *
  47.  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  48.  * Dual licensed under the MIT or GPL Version 2 licenses.
  49.  * http://jquery.org/license
  50.  *
  51.  * http://docs.jquery.com/UI/Dialog
  52.  *
  53.  * Depends:
  54.  * jquery.ui.core.js
  55.  * jquery.ui.widget.js
  56.  * jquery.ui.button.js
  57.  * jquery.ui.draggable.js
  58.  * jquery.ui.mouse.js
  59.  * jquery.ui.position.js
  60.  * jquery.ui.resizable.js
  61.  */
  62.  
  63. (function($) {
  64. // Get the dialog widget factory prototype
  65. var proto = $.ui.dialog.prototype;
  66.  
  67. // Members need access to these class names
  68. var uiDialogClasses = 'ui-dialog ' + 'ui-widget ' + 'ui-widget-content ' + 'ui-corner-all ';
  69.  
  70. // Internal function used to generate a random ID
  71. function randomID() {
  72. var id = "";
  73. for ( var i = 1; i <= 10; i++)
  74. id += (Math.floor(Math.random() * 10) + 1);
  75. return id;
  76. }
  77.  
  78. // To fade in the overlay without it going crazy, we need to know the opacity level
  79. // set in the CSS
  80. var overlayOpacity;
  81. var overlayTestID = randomID();
  82. var overlayReg = /Opacity=(\d+)/;
  83.  
  84. // Extract the opacity level
  85. $("body").append("<div id='" + overlayTestID + "' class='ui-widget-overlay' style='display: none;'></div>");
  86.  
  87. try {
  88. var overlayFilter = $("#" + overlayTestID).css("filter");
  89. if (overlayReg.test(overlayFilter))
  90. overlayOpacity = overlayReg.exec(overlayFilter)[1];
  91. }
  92. catch (ex){}
  93.  
  94. // If no overlay opacity is defined, assume 0 opacity
  95. if (!overlayOpacity)
  96. overlayOpacity = 0;
  97.  
  98. $("#" + overlayTestID).remove();
  99.  
  100. // Store the modified create() method
  101. var _createMod = function() {
  102. this.originalTitle = this.element.attr('title');
  103. // #5742 - .attr() might return a DOMElement
  104. if (typeof this.originalTitle !== "string")
  105. this.originalTitle = "";
  106. var self = this, options = self.options,
  107.  
  108. title = options.title || self.originalTitle || '&#160;', titleId = $.ui.dialog
  109. .getTitleId(self.element),
  110.  
  111. uiDialog = (self.uiDialog = $('<div></div>')).appendTo(document.body)
  112. .hide().addClass(uiDialogClasses + options.dialogClass).css( {
  113. zIndex : options.zIndex
  114. })
  115. // setting tabIndex makes the div focusable
  116. // setting outline to 0 prevents a border on focus in Mozilla
  117. .attr('tabIndex', -1).css('outline', 0).keydown(
  118. function(event) {
  119. if (options.closeOnEscape && event.keyCode
  120. && event.keyCode === $.ui.keyCode.ESCAPE) {
  121.  
  122. self.close(event);
  123. event.preventDefault();
  124. }
  125. }).attr( {
  126. role : 'dialog',
  127. 'aria-labelledby' : titleId
  128. }).mousedown(function(event) {
  129. self.moveToTop(false, event);
  130. }),
  131.  
  132. uiDialogContent = self.element.show().removeAttr('title').addClass(
  133. 'ui-dialog-content ' + 'ui-widget-content').appendTo(uiDialog),
  134.  
  135. uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
  136. .addClass(
  137. 'ui-dialog-titlebar ' + 'ui-widget-header ' + 'ui-corner-all ' + 'ui-helper-clearfix')
  138. .prependTo(uiDialog);
  139.  
  140. // Control the creation of the close 'X'
  141. if (options.hasClose)
  142. var uiDialogTitlebarClose = $('<a href="#"></a>').addClass(
  143. 'ui-dialog-titlebar-close ' + 'ui-corner-all').attr('role',
  144. 'button').hover(function() {
  145. uiDialogTitlebarClose.addClass('ui-state-hover');
  146. }, function() {
  147. uiDialogTitlebarClose.removeClass('ui-state-hover');
  148. }).focus(function() {
  149. uiDialogTitlebarClose.addClass('ui-state-focus');
  150. }).blur(function() {
  151. uiDialogTitlebarClose.removeClass('ui-state-focus');
  152. }).click(function(event) {
  153. self.close(event);
  154. return false;
  155. }).appendTo(uiDialogTitlebar),
  156.  
  157. uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
  158. .addClass('ui-icon ' + 'ui-icon-closethick').text(
  159. options.closeText).appendTo(uiDialogTitlebarClose);
  160.  
  161. var uiDialogTitle = $('<span></span>').addClass('ui-dialog-title')
  162. .attr('id', titleId).html(title).prependTo(uiDialogTitlebar);
  163.  
  164. // handling of deprecated beforeclose (vs beforeClose) option
  165. // Ticket #4669 http://dev.jqueryui.com/ticket/4669
  166. // TODO: remove in 1.9pre
  167. if ($.isFunction(options.beforeclose)
  168. && !$.isFunction(options.beforeClose))
  169. options.beforeClose = options.beforeclose;
  170.  
  171. uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
  172.  
  173. if (options.draggable && $.fn.draggable)
  174. self._makeDraggable();
  175. if (options.resizable && $.fn.resizable)
  176. self._makeResizable();
  177. self._createButtons(options.buttons);
  178. self._isOpen = false;
  179. if ($.fn.bgiframe)
  180. uiDialog.bgiframe();
  181. };
  182.  
  183. // Override the destroy method to control the overlay
  184. proto.destroy = function() {
  185. var self = this;
  186. self.uiDialog.hide();
  187. self.element.unbind('.dialog').removeData('dialog').removeClass(
  188. 'ui-dialog-content ui-widget-content').hide().appendTo('body');
  189. self.uiDialog.remove();
  190. if (self.originalTitle)
  191. self.element.attr('title', self.originalTitle);
  192. return self;
  193. };
  194.  
  195. proto.close = function() {
  196. $.hideDialog();
  197. };
  198.  
  199. // Override the open method to add fadeIn effect
  200. proto.open = function(){
  201. if (this._isOpen)
  202. return;
  203.  
  204. var self = this, options = self.options, uiDialog = self.uiDialog;
  205.  
  206. // If an overlay is open, remember that
  207. var overlayOpen = $(".ui-widget-overlay:visible").size() != 0;
  208.  
  209. // Open overlay
  210. self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
  211.  
  212. if (uiDialog.next().length)
  213. uiDialog.appendTo('body');
  214.  
  215. self._size();
  216. self._position(options.position);
  217.  
  218. var $dialog = uiDialog.show(options.show);
  219.  
  220. // Fix the modal positioning in IE
  221. if (options.modal)
  222. $(".ui-widget-overlay").css("position", "fixed")
  223.  
  224. // Add fadeIn effect
  225. if (options.fadeIn) {
  226. if (!overlayOpen && options.modal){
  227. // IE needs to have the filter attribute applied before it fades in
  228. $(".ui-widget-overlay").hide().css('filter', 'alpha(opacity=' + overlayOpacity + ')').fadeIn("normal");
  229. }
  230. $dialog.hide().fadeIn("normal");
  231. }
  232.  
  233. self.moveToTop(true);
  234.  
  235. // prevent tabbing out of modal dialogs
  236. if (options.modal) {
  237. uiDialog.bind('keypress.ui-dialog', function(event) {
  238. if (event.keyCode !== $.ui.keyCode.TAB)
  239. return;
  240.  
  241. var tabbables = $(':tabbable', this), first = tabbables
  242. .filter(':first'), last = tabbables.filter(':last');
  243.  
  244. if (event.target === last[0] && !event.shiftKey) {
  245. first.focus(1);
  246. return false;
  247. } else if (event.target === first[0] && event.shiftKey) {
  248. last.focus(1);
  249. return false;
  250. }
  251. });
  252. }
  253.  
  254. // set focus to the first tabbable element in the content area or the
  255. // first button
  256. // if there are no tabbable elements, set focus on the dialog itself
  257. $(
  258. self.element.find(':tabbable').get().concat(
  259. uiDialog.find('.ui-dialog-buttonpane :tabbable').get()
  260. .concat(uiDialog.get()))).eq(0).focus();
  261.  
  262. self._trigger('open');
  263. self._isOpen = true;
  264.  
  265. return self;
  266. };
  267.  
  268. // Internal function used for getting the element on top
  269. function getTopElement(elems) {
  270. // Store the greates z-index that has been seen so far
  271. var maxZ = 0;
  272. // Stores a reference to the element that has the greatest z-index so
  273. // far
  274. var maxElem;
  275. // Check each element's z-index
  276. elems.each(function() {
  277. // If it's bigger than the currently biggest one, store the value
  278. // and reference
  279. if ($(this).css("z-index") > maxZ) {
  280. maxElem = $(this);
  281. maxZ = $(this).css("z-index");
  282. }
  283. });
  284. // Finally, return the reference to the element on top
  285. return maxElem;
  286. }
  287.  
  288. $.showDialog = function(title, prompt, args) {
  289. var options = {
  290. resizable : false,
  291. draggable : true,
  292. closeOnEscape : false,
  293. moveToTop : true,
  294. title : title,
  295. hasClose : true,
  296. fadeIn : true
  297. };
  298.  
  299. $.extend(options, args);
  300.  
  301. // Add some custom options
  302. if (!options.hasClose)
  303. $dialog._create = _createMod;
  304.  
  305. var id = randomID();
  306.  
  307. if ($("#dialogContainer").size() == 0)
  308. $("body").append("<div id='dialogContainer'></div>");
  309.  
  310. // Add a div for the dialog after the special dialogContainer target div
  311. $("#dialogContainer").after(
  312. "<div id='m" + id + "'><p><div id='mp" + id + "'>" + prompt
  313. + "</div></p></div>");
  314.  
  315. $("#m" + id).dialog(options);
  316.  
  317. // Remove duplicate overlays
  318. if ($(".ui-widget-overlay").size() > 1)
  319. $(".ui-widget-overlay:first").remove();
  320.  
  321. return id;
  322. };
  323.  
  324. $.hideDialog = function(id, fadeOut) {
  325. // If an ID was not supplied, get the ID of the dialog currently on top
  326. id = id
  327. || "#"
  328. + getTopElement($(".ui-dialog")).find(".ui-dialog-content")
  329. .attr("id");
  330.  
  331. fadeOut = fadeOut || true;
  332.  
  333. // Remove the dialog
  334. $(id).parent().andSelf().remove();
  335.  
  336. // If no dialogs are currently visible, remove the overlay
  337. if ($(".ui-dialog:visible").size() === 0) {
  338. if (fadeOut)
  339. $(".ui-widget-overlay").fadeOut("normal");
  340. else
  341. $(".ui-widget-overlay").hide();
  342. } else {
  343. // If one or more overlays exist, change the z-index of the overlay
  344. // so it is below the top-most dialog
  345. $(".ui-widget-overlay")
  346. .css(
  347. {
  348. "z-index" : parseInt(
  349. getTopElement($(".ui-dialog:visible"))
  350. .css("z-index"), 10) - 1
  351. });
  352. }
  353. // Remove event blocking left over from the overlay
  354. $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
  355. function(event) {
  356. $(document).unbind(event + '.dialog-overlay');
  357. });
  358. };
  359. $.clearDialogs = function(fadeOut) {
  360. fadeOut = fadeOut || true;
  361. // Find all the dialogs
  362. $(".ui-dialog").each(function() {
  363. // Remove them
  364. $(this).find(".ui-dialog-content").parent().andSelf().remove();
  365. });
  366. // Remove the overlay
  367. if (fadeOut)
  368. $(".ui-widget-overlay").fadeOut("normal");
  369. else
  370. $(".ui-widget-overlay").hide();
  371. // Remove event blocking left over from the overlay
  372. $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
  373. function(event) {
  374. $(document).unbind(event + '.dialog-overlay');
  375. });
  376. };
  377.  
  378. $.alert = function(prompt, arg) {
  379. var args;
  380. args = $.extend(args, arg, {
  381. buttons : {
  382. "Ok" : function() {
  383. // When the Ok button is clicked, just hide this dialog
  384. $.hideDialog(this);
  385. }
  386. }
  387. } );
  388. return $.showDialog("Info", prompt, args);
  389. };
  390.  
  391. $.confirm = function(prompt, yes, no, arg) {
  392. var args;
  393. args = $.extend(args, arg, {
  394. buttons : {
  395. "No" : function() {
  396. (no || $.noop).call();
  397. $.hideDialog(this);
  398. },
  399. "Yes" : function() {
  400. (yes || $.noop).call();
  401. $.hideDialog(this);
  402. }
  403. }
  404. });
  405. return $.showDialog("Confirm", prompt, args);
  406. };
  407.  
  408. })(jQuery);

Report this snippet  

You need to login to post a comment.