Advertisement
Guest User

jqModal with Escape on Close

a guest
Feb 21st, 2014
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.46 KB | None | 0 0
  1.  
  2. /*
  3. * jqModal - Minimalist Modaling with jQuery
  4. *
  5. * Copyright (c) 2007-2014 Brice Burgess @iceburg_net
  6. * Dual licensed under the MIT and GPL licenses:
  7. * http://www.opensource.org/licenses/mit-license.php
  8. * http://www.gnu.org/licenses/gpl.html
  9. *
  10. * $Version: 2014.01.30 +r17 (aka 1.0.0)
  11. * Requires: jQuery 1.2.3+
  12. */
  13.  
  14. (function(jQuery, window, undefined) {
  15.  
  16. /**
  17. * Initialize a set of elements as "modals". Modals typically are popup dialogs,
  18. * notices, modal windows, &c.
  19. *
  20. * @name jqm
  21. * @param options user defined options, augments defaults.
  22. * @type jQuery
  23. * @cat Plugins/jqModal
  24. */
  25.  
  26. $.fn.jqm=function(options){
  27.  
  28. var o = $.extend({}, $.jqm.params, options);
  29.  
  30. return this.each(function(){
  31. var e = $(this),
  32. jqm = $(this).data('jqm');
  33.  
  34. if(!jqm) jqm = {ID: I++};
  35.  
  36. // add/extend options to modal and mark as initialized
  37. e.data('jqm',$.extend(o,jqm)).addClass('jqm-init');
  38.  
  39. // ... Attach events to trigger showing of this modal
  40. o.trigger&&$(this).jqmAddTrigger(o.trigger);
  41. });
  42. };
  43.  
  44.  
  45. /**
  46. * Matching modals will have their jqmShow() method fired by attaching a
  47. * onClick event to elements matching `trigger`.
  48. *
  49. * @name jqmAddTrigger
  50. * @param trigger a selector String, jQuery collection of elements, or a DOM element.
  51. */
  52. $.fn.jqmAddTrigger=function(trigger){
  53. return this.each(function(){
  54. if(!addTrigger($(this), 'jqmShow', trigger))
  55. err("jqmAddTrigger must be called on initialized modals")
  56. });
  57. };
  58.  
  59.  
  60. /**
  61. * Matching modals will have their jqmHide() method fired by attaching an
  62. * onClick event to elements matching `trigger`.
  63. *
  64. * @name jqmAddClose
  65. * @param trigger a selector String, jQuery collection of elements, or a DOM element.
  66. */
  67. $.fn.jqmAddClose=function(trigger){
  68. return this.each(function(){
  69. if(!addTrigger($(this), 'jqmHide', trigger))
  70. err("jqmAddClose must be called on initialized modals")
  71. });
  72. };
  73.  
  74.  
  75. /**
  76. * Open matching modals (if not shown)
  77. */
  78. $.fn.jqmShow=function(trigger){
  79. return this.each(function(){ !this._jqmShown&&show($(this), trigger); });
  80. };
  81.  
  82. /**
  83. * Close matching modals
  84. */
  85. $.fn.jqmHide=function(trigger){
  86. return this.each(function(){ this._jqmShown&&hide($(this), trigger); });
  87. };
  88.  
  89.  
  90. // utility functions
  91.  
  92. var
  93. err = function(msg){
  94. if(window.console && window.console.error) window.console.error(msg);
  95.  
  96.  
  97. }, show = function(e, t){
  98.  
  99. /**
  100. * e = modal element (as jQuery object)
  101. * t = triggering element
  102. *
  103. * o = options
  104. * z = z-index of modal
  105. * v = overlay element (as jQuery object)
  106. * h = hash (for jqModal <= r15 compatibility)
  107. */
  108.  
  109. var o = e.data('jqm'),
  110. t = t || window.event,
  111. z = (parseInt(e.css('z-index'))),
  112. z = (z > 0) ? z : 3000,
  113. v = $('<div></div>').addClass(o.overlayClass).css({height:'100%',width:'100%',position:'fixed',left:0,top:0,'z-index':z-1,opacity:o.overlay/100});
  114.  
  115. // maintain legacy "hash" construct
  116. h = {w: e, c: o, o: v, t: t};
  117.  
  118. e.css('z-index',z);
  119.  
  120. if(o.ajax){
  121. var target = o.target || e,
  122. url = o.ajax;
  123.  
  124. target = (typeof target == 'string') ? $(target,e) : $(target);
  125. if(url.substr(0,1) == '@') url = $(t).attr(url.substring(1));
  126.  
  127. // Load the Ajax Content (and once loaded);
  128. // Fire the onLoad callback (if exists),
  129. // Attach closing events to elements inside the modal that match the closingClass,
  130. // and Execute the jqModal default Open Callback
  131. target.html(o.ajaxText).load(url,function(){
  132. o.onLoad && o.onLoad.call(this,h);
  133. open(h);
  134. });
  135. }
  136. else { open(h); }
  137.  
  138. }, hide = function(e, t){
  139. /**
  140. * e = modal element (as jQuery object)
  141. * t = triggering element
  142. *
  143. * o = options
  144. * h = hash (for jqModal <= r15 compatibility)
  145. */
  146.  
  147. var o = e.data('jqm'),
  148. t = t || window.event,
  149.  
  150. // maintain legacy "hash" construct
  151. h = {w: e, c: o, o: e.data('jqmv'), t: t};
  152.  
  153. close(h);
  154.  
  155. }, onShow = function(hash){
  156. // onShow callback. Responsible for showing a modal and overlay.
  157. // return false to stop opening modal.
  158.  
  159. // hash object;
  160. // w: (jQuery object) The modal element
  161. // c: (object) The modal's options object
  162. // o: (jQuery object) The overlay element
  163. // t: (DOM object) The triggering element
  164.  
  165. // display the overlay (prepend to body) if not disabled
  166. if(hash.c.overlay > 0)
  167. hash.o.prependTo('body');
  168.  
  169. // make modal visible
  170. hash.w.show();
  171.  
  172. // call focusFunc (attempts to focus on first input in modal)
  173. $.jqm.focusFunc(hash.w);
  174.  
  175. return true;
  176.  
  177.  
  178. }, onHide = function(hash){
  179. // onHide callback. Responsible for hiding a modal and overlay.
  180. // return false to stop closing modal.
  181.  
  182. // hash object;
  183. // w: (jQuery object) The modal element
  184. // c: (object) The modal's options object
  185. // o: (jQuery object) The overlay element
  186. // t: (DOM object) The triggering element
  187.  
  188. // hide modal and if overlay, remove overlay.
  189. hash.w.hide() && hash.o && hash.o.remove();
  190.  
  191. return true;
  192.  
  193.  
  194. }, addTrigger = function(e, key, trigger){
  195. // addTrigger: Adds a jqmShow or jqmHide (key) for a modal (e)
  196. // all elements that match trigger string (trigger)\
  197.  
  198. // return false if e is not an initialized modal element
  199. if(!e.data('jqm')) return false;
  200.  
  201. return $(trigger).each(function(){
  202. // register modal to trigger elements
  203. this[key] = this[key] || [];
  204. this[key].push(e);
  205.  
  206. }).click(function(){
  207.  
  208. var trigger = this;
  209.  
  210. // foreadh modal registered to this trigger, call jqmShow ||
  211. // jqmHide (key) on modal passing trigger element (e)
  212. $.each(this[key], function(i, e){ e[key](trigger); });
  213.  
  214. // stop trigger click event from bubbling
  215. return false;
  216. });
  217.  
  218.  
  219. }, open = function(h){
  220. // open: executes the onOpen callback + performs common tasks if successful
  221.  
  222. // transform legacy hash into new var shortcuts
  223. var e = h.w,
  224. v = h.o,
  225. o = h.c,
  226. modal = $(h.w);
  227.  
  228. // execute onShow callback
  229. if(o.onShow(h) !== false){
  230. // mark modal as shown
  231. e[0]._jqmShown = true;
  232.  
  233. // if modal dialog
  234. //
  235. // Bind the Keep Focus Function [F] if no other Modals are open (!A[0]) +
  236. // Add this modal to the opened modals stack (A) for nested modal support
  237. //
  238. // else, close dialog when overlay is clicked
  239. if(o.modal){ !A[0]&&F('bind'); A.push(e); }
  240. else e.jqmAddClose(v);
  241.  
  242. // Attach closing events to elements inside the modal that match the closingClass
  243. o.closeClass&&e.jqmAddClose($('.' + o.closeClass,e));
  244.  
  245. // IF toTop is true and overlay exists;
  246. // Add placeholder element <span id="jqmP#ID_of_modal"/> before modal to
  247. // remember it's position in the DOM and move it to a child of the body tag (after overlay)
  248. o.toTop&&v&&e.before('<span id="jqmP'+o.ID+'"></span>').insertAfter(v);
  249.  
  250. // remember overlay (for closing function)
  251. e.data('jqmv',v);
  252.  
  253.  
  254. modal.unbind("keydown");
  255.  
  256. if (o.closeOnEsc) {
  257. modal.attr("tabindex", 0);
  258. modal.bind("keydown", function (event) {
  259. if (event.keyCode == 27) {
  260. event.preventDefault();
  261. modal.jqmHide();
  262. }
  263. });
  264. modal.focus();
  265. }
  266. }
  267.  
  268.  
  269. }, close = function(h){
  270. // close: executes the onHide callback + performs common tasks if successful
  271.  
  272. // transform legacy hash into new var shortcuts
  273. var e = h.w,
  274. v = h.o,
  275. o = h.c;
  276.  
  277. // execute onShow callback
  278. if(o.onHide(h) !== false){
  279. // mark modal as !shown
  280. e[0]._jqmShown = false;
  281.  
  282. // If modal, remove from modal stack.
  283. // If no modals in modal stack, unbind the Keep Focus Function
  284. if(o.modal){A.pop();!A[0]&&F('unbind');}
  285.  
  286. // IF toTop was passed and an overlay exists;
  287. // Move modal back to its "remembered" position.
  288. o.toTop&&v&&$('#jqmP'+o.ID).after(e).remove();
  289. }
  290.  
  291.  
  292. }, F = function(t){
  293. // F: The Keep Focus Function (for modal: true dialos)
  294. // Binds or Unbinds (t) the Focus Examination Function (X) to keypresses and clicks
  295.  
  296. $(document)[t]("keypress keydown mousedown",X);
  297.  
  298.  
  299. }, X = function(e){
  300. // X: The Focus Examination Function (for modal: true dialogs)
  301.  
  302. var modal = $(e.target).data('jqm') || $(e.target).parents('.jqm-init:first').data('jqm'),
  303. activeModal = A[A.length-1].data('jqm');
  304.  
  305. // allow bubbling if event target is within active modal dialog
  306. if(modal && modal.ID == activeModal.ID) return true;
  307.  
  308. // else, trigger focusFunc (focus on first input element and halt bubbling)
  309. return $.jqm.focusFunc(activeModal);
  310. },
  311.  
  312. I = 0, // modal ID increment (for nested modals)
  313. A = []; // array of active modals (used to lock interactivity to appropriate modal)
  314.  
  315.  
  316. // $.jqm, overridable defaults
  317. $.jqm = {
  318. /**
  319. * default options
  320. *
  321. * (Integer) overlay - [0-100] Translucency percentage (opacity) of the body covering overlay. Set to 0 for NO overlay, and up to 100 for a 100% opaque overlay.
  322. * (String) overlayClass - Applied to the body covering overlay. Useful for controlling overlay look (tint, background-image, &c) with CSS.
  323. * (String) closeClass - Children of the modal element matching `closeClass` will fire the onHide event (to close the modal).
  324. * (Mixed) trigger - Matching elements will fire the onShow event (to display the modal). Trigger can be a selector String, a jQuery collection of elements, a DOM element, or a False boolean.
  325. * (String) ajax - URL to load content from via an AJAX request. False to disable ajax. If ajax begins with a "@", the URL is extracted from the attribute of the triggering element (e.g. use '@data-url' for; <a href="#" class="jqModal" data-url="modal.html">...)
  326. * (Mixed) target - Children of the modal element to load the ajax response into. If false, modal content will be overwritten by ajax response. Useful for retaining modal design.
  327. * Target may be a selector string, jQuery collection of elements, or a DOM element -- and MUST exist as a child of the modal element.
  328. * (String) ajaxText - Text shown while waiting for ajax return. Replaces HTML content of `target` element.
  329. * (Boolean) modal - If true, user interactivity will be locked to the modal window until closed.
  330. * (Boolean) toTop - If true, modal will be posistioned as a first child of the BODY element when opened, and its DOM posistion restored when closed. Useful for overcoming z-Index container issues.
  331. * (Function) onShow - User defined callback function fired when modal opened.
  332. * (Function) onHide - User defined callback function fired when modal closed.
  333. * (Function) onLoad - User defined callback function fired when ajax content loads.
  334. */
  335. params: {
  336. overlay: 50,
  337. overlayClass: 'jqmOverlay',
  338. closeClass: 'jqmClose',
  339. trigger: '.jqModal',
  340. ajax: false,
  341. target: false,
  342. ajaxText: '',
  343. modal: false,
  344. toTop: false,
  345. onShow: onShow,
  346. onHide: onHide,
  347. onLoad: false,
  348. closeOnEsc: true
  349. },
  350.  
  351. // focusFunc is fired when a modal is shown, or when interaction occurs outside
  352. // a modal enabled dialog. Passed the modal element.
  353. focusFunc: function(e) { $(':input:visible:first',e).focus(); return false; }
  354. };
  355.  
  356. })( jQuery, window );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement