1/* 2 * jQuery.dockmodal - jQuery dockable modal dialog widget 3 * 4 * Copyright 2014, uxMine 5 * Dual licensed under the MIT or GPL Version 2 licenses. 6 * Date: 2/11/2014 7 * @author Tarafder Ashek E Elahi 8 * @version 1.1 9 * Depends: 10 * jquery.js 11 * 12 */ 13 14; 15(function ($) { 16 var defaults = { 17 width: 400, 18 height: "65%", 19 minimizedWidth: 200, 20 gutter: 10, 21 poppedOutDistance: "6%", 22 title: "", 23 dialogClass: "", 24 buttons: [], /* id, html, buttonClass, click */ 25 animationSpeed: 400, 26 opacity: 1, 27 initialState: 'modal', /* "modal", "docked", "minimized" */ 28 29 showClose: true, 30 showPopout: true, 31 showMinimize: true, 32 33 create: undefined, 34 open: undefined, 35 beforeClose: undefined, 36 close: undefined, 37 beforeMinimize: undefined, 38 minimize: undefined, 39 beforeRestore: undefined, 40 restore: undefined, 41 beforePopout: undefined, 42 popout: undefined 43 }; 44 var dClass = "dockmodal"; 45 var windowWidth = $(window).width(); 46 47 function setAnimationCSS($this, $el) { 48 var aniSpeed = $this.options.animationSpeed / 1000; 49 $el.css({"transition": aniSpeed + "s right, " + aniSpeed + "s left, " + aniSpeed + "s top, " + aniSpeed + "s bottom, " + aniSpeed + "s height, " + aniSpeed + "s width"}); 50 return true; 51 } 52 53 function removeAnimationCSS($el) { 54 $el.css({"transition": "none"}); 55 return true; 56 } 57 58 var methods = { 59 init: function (options) { 60 61 return this.each(function () { 62 63 var $this = $(this); 64 65 var data = $this.data('dockmodal'); 66 $this.options = $.extend({}, defaults, options); 67 68 // If the plugin hasn't been initialized yet 69 if (!data) { 70 $this.data('dockmodal', $this); 71 } else { 72 $("body").append($this.closest("." + dClass).show()); 73 //methods.restore.apply($this); 74 methods.refreshLayout(); 75 setTimeout(function () { 76 methods.restore.apply($this); 77 }, $this.options.animationSpeed); 78 return; 79 } 80 81 // create modal 82 var $body = $("body"); 83 var $window = $(window); 84 var $dockModal = $('<div/>').addClass(dClass).addClass($this.options.dialogClass); 85 if ($this.options.initialState == "modal") { 86 $dockModal.addClass("popped-out"); 87 } else if ($this.options.initialState == "minimized") { 88 $dockModal.addClass("minimized"); 89 } 90 //$dockModal.width($this.options.width); 91 $dockModal.height(0); 92 setAnimationCSS($this, $dockModal); 93 94 // create title 95 var $dockHeader = $('<div></div>').addClass(dClass + "-header"); 96 if ($this.options.showClose) { 97 $('<a href="#" class="header-action action-close" title="Close"><i class="icon-dockmodal-close"></i></a>').appendTo($dockHeader).click(function (e) { 98 methods.destroy.apply($this); 99 return false; 100 }); 101 } 102 if ($this.options.showPopout) { 103 $('<a href="#" class="header-action action-popout" title="Pop out"><i class="icon-dockmodal-popout"></i></a>').appendTo($dockHeader).click(function (e) { 104 if ($dockModal.hasClass("popped-out")) { 105 methods.restore.apply($this); 106 } else { 107 methods.popout.apply($this); 108 } 109 return false; 110 }); 111 } 112 if ($this.options.showMinimize) { 113 $('<a href="#" class="header-action action-minimize" title="Minimize"><i class="icon-dockmodal-minimize"></i></a>
113').appendTo($dockHeader).click(function (e) { 114 if ($dockModal.hasClass("minimized")) { 115 if ($dockModal.hasClass("popped-out")) { 116 methods.popout.apply($this); 117 } else { 118 methods.restore.apply($this); 119 } 120 } else { 121 methods.minimize.apply($this); 122 } 123 return false; 124 }); 125 } 126 if ($this.options.showMinimize && $this.options.showPopout) { 127 $dockHeader.click(function () { 128 if ($dockModal.hasClass("minimized")) { 129 if ($dockModal.hasClass("popped-out")) { 130 methods.popout.apply($this); 131 } else { 132 methods.restore.apply($this); 133 } 134 } else { 135 methods.minimize.apply($this); 136 } 137 return false; 138 }); 139 } else { 140 $dockHeader.click(function () { 141 if ($dockModal.hasClass("minimized")) { 142 methods.popout.apply($this); 143 } else { 144 methods.minimize.apply($this); 145 } 146 return false; 147 }); 148 } 149 $dockHeader.append('<div class="title-text">' + ($this.options.title || $this.attr("title")) + '</div>'); 150 $dockModal.append($dockHeader); 151 152 // create body section 153 var $placeholder = $('<div class="modal-placeholder"></div>').insertAfter($this); 154 $this.placeholder = $placeholder; 155 var $dockBody = $('<div></div>').addClass(dClass + "-body").append($this); 156 $dockModal.append($dockBody); 157 158 // create footer 159 if ($this.options.buttons.length) { 160 var $dockFooter = $('<div></div>').addClass(dClass + "-footer"); 161 var $dockFooterButtonset = $('<div></div>').addClass(dClass + "-footer-buttonset"); 162 $dockFooter.append($dockFooterButtonset); 163 $.each($this.options.buttons, function (indx, el) { 164 var $btn = $('<a href="#" class="btn"></a>'); 165 $btn.attr({ "id": el.id, "class": el.buttonClass }); 166 $btn.html(el.html); 167 $btn.click(function (e) { 168 el.click(e, $this); 169 return false; 170 }); 171 $dockFooterButtonset.append($btn); 172 }); 173 $dockModal.append($dockFooter); 174 } else { 175 $dockModal.addClass("no-footer"); 176 } 177 178 // create overlay
179 var $overlay = $("." + dClass + "-overlay"); 180 if (!$overlay.length) { 181 $overlay = $('<div/>').addClass(dClass + "-overlay"); 182 } 183 184 // raise create event 185 if ($.isFunction($this.options.create)) { 186 $this.options.create($this); 187 } 188 189 $body.append($dockModal); 190 $dockModal.after($overlay); 191 $dockBody.focus(); 192 193 // raise open event 194 if ($.isFunction($this.options.open)) { 195 setTimeout(function () { 196 $this.options.open($this); 197 }, $this.options.animationSpeed); 198 } 199 200 //methods.restore.apply($this); 201 if ($dockModal.hasClass("minimized")) { 202 $dockModal.find(".dockmodal-body, .dockmodal-footer").hide(); 203 methods.minimize.apply($this); 204 } else { 205 if ($dockModal.hasClass("popped-out")) { 206 methods.popout.apply($this); 207 } else { 208 methods.restore.apply($this); 209 } 210 } 211 212 // attach resize event 213 // track width, set to window width 214 $body.data("windowWidth", $window.width()); 215 216 $window.unbind("resize.dockmodal").bind("resize.dockmodal", function () { 217 // do nothing if the width is the same 218 // update new width value 219 if ($window.width() == $body.data("windowWidth")) { 220 return; 221 } 222 223 $body.data("windowWidth", $window.width()); 224 methods.refreshLayout(); 225 }); 226 }); 227 }, 228 destroy: function () { 229 return this.each(function () { 230 231 var $this = $(this).data('dockmodal'); 232 if (!$this) 233 return; 234 235 // raise beforeClose event 236 if ($.isFunction($this.options.beforeClose)) { 237 if ($this.options.beforeClose($this) === false) { 238 return; 239 } 240 } 241 242 try { 243 var $dockModal = $this.closest("." + dClass); 244 245 if ($dockModal.hasClass("popped-out") && !$dockModal.hasClass("minimized")) { 246 $dockModal.css({ 247 "left": "50%", 248 "right": "50%", 249 "top": "50%", 250 "bottom": "50%" 251 }); 252 } else { 253 $dockModal.css({ 254 "width": "0", 255 "height": "0" 256 }); 257 } 258 setTimeout(function () { 259 $this.removeData('dockmodal'); 260 $this.placeholder.replaceWith($this); 261 $dockModal.remove(); 262 $("." + dClass + "-overlay").hide(); 263 methods.refreshLayout(); 264 265 // raise close event 266 if ($.isFunction($this.options.close)) { 267 $this.options.close($this); 268 } 269 }, $this.options.animationSpeed); 270 271 } 272 catch (err) { 273 alert(err.message); 274 } 275 // other destroy routines 276 277 }) 278 }, 279 close: function () { 280 methods.destroy.apply(this); 281 }, 282 minimize: function () { 283 return this.each(function () { 284 285 var $this = $(this).data('dockmodal'); 286 if (!$this) 287 return; 288 289 // raise beforeMinimize event 290 if ($.isFunction($this.options.beforeMinimize)) { 291 if ($this.options.beforeMinimize($this) === false) { 292 return; 293 } 294 } 295 296 var $dockModal = $this.closest("." + dClass); 297 var headerHeight = $dockModal.find(".dockmodal-header").outerHeight(); 298 $dockModal.addClass("minimized").css({ 299 "width": $this.options.minimizedWidth + "px", 300 "height": headerHeight + "px", 301 "left": "auto", 302 "right": "auto", 303 "top": "auto", 304 "bottom": "0" 305 }); 306 setTimeout(function () { 307 // for safty, hide the body and footer 308 $dockModal.find(".dockmodal-body, .dockmodal-footer").hide(); 309 310 // raise minimize event 311 if ($.isFunction($this.options.minimize)) { 312 $this.options.minimize($this); 313 } 314 }, $this.options.animationSpeed); 315 316 $("." + dClass + "-overlay").hide(); 317 $dockModal.find(".action-minimize").attr("title", "Restore"); 318 319 methods.refreshLayout(); 320 }) 321 }, 322 restore: function () { 323 return this.each(function () { 324 325 var $this = $(this).data('dockmodal'); 326 if (!$this) 327 return; 328 329 // raise beforeRestore event 330 if ($.isFunction($this.options.beforeRestore)) { 331 if ($this.options.beforeRestore($this) === false) { 332 return; 333 } 334 } 335 336 var $dockModal = $this.closest("." + dClass); 337 $dockModal.removeClass("minimized popped-out"); 338 $dockModal.find(".dockmodal-body, .dockmodal-footer").show(); 339 $dockModal.css({ 340 "width": $this.options.width + "px", 341 "height": $this.options.height, 342 "left": "auto", 343 "right": "auto", 344 "top": "auto", 345 "bottom": "0" 346 }); 347 348 $("." + dClass + "-overlay").hide(); 349 $dockModal.find(".action-minimize").attr("title", "Minimize"); 350 $dockModal.find(".action-popout").attr("title", "Pop-out"); 351 352 setTimeout(function () { 353 // raise restore event 354 if ($.isFunction($this.options.restore)) { 355 $this.options.restore($this); 356 } 357 }, $this.options.animationSpeed); 358 359 methods.refreshLayout(); 360 }) 361 }, 362 popout: function () { 363 return this.each(function () { 364 365 var $this = $(this).data('dockmodal'); 366 if (!$this) 367 return; 368 369 // raise beforePopout event 370 if ($.isFunction($this.options.beforePopout)) { 371 if ($this.options.beforePopout($this) === false) { 372 return; 373 } 374 } 375 376 var $dockModal = $this.closest("." + dClass); 377 $dockModal.find(".dockmodal-body, .dockmodal-footer").show(); 378 379 // prepare element for animation 380 removeAnimationCSS($dockModal); 381 var offset = $dockModal.position(); 382 var windowWidth = $(window).width(); 383 $dockModal.css({ 384 "width": "auto", 385 "height": "auto", 386 "left": offset.left + "px", 387 "right": (windowWidth - offset.left - $dockModal.outerWidth(true)) + "px", 388 "top": offset.top + "px", 389 "bottom": 0 390 }); 391 392 setAnimationCSS($this, $dockModal); 393 setTimeout(function () { 394 $dockModal.removeClass("minimized").addClass("popped-out").css({ 395 "width": "auto", 396 "height": "auto", 397 "left": $this.options.poppedOutDistance, 398 "right": $this.options.poppedOutDistance, 399 "top": "50px", 400 "bottom": $this.options.poppedOutDistance 401 }); 402 $("." + dClass + "-overlay").show(); 403 $dockModal.find(".action-popout").attr("title", "Pop-in"); 404 405 methods.refreshLayout(); 406 }, 10); 407 408 setTimeout(function () { 409 // raise popout event 410 if ($.isFunction($this.options.popout)) { 411 $this.options.popout($this); 412 } 413 }, $this.options.animationSpeed); 414 }); 415 }, 416 refreshLayout: function () { 417 418 var right = 0; 419 var windowWidth = $(window).width(); 420 421 $.each($("." + dClass).toArray().reverse(), function (i, val) { 422 var $dockModal = $(this); 423 var $this = $dockModal.find("." + dClass + "-body > div").data("dockmodal"); 424 425 if ($dockModal.hasClass("popped-out") && !$dockModal.hasClass("minimized")) { 426 return; 427 } 428 right += $this.options.gutter; 429 $dockModal.css({ "right": right + "px" }); 430 if ($dockModal.hasClass("minimized")) { 431 right += $this.options.minimizedWidth; 432 } else { 433 right += $this.options.width; 434 } 435 if (right > windowWidth) { 436 $dockModal.hide(); 437 } else { 438 setTimeout(function () { 439 $dockModal.show(); 440 }, $this.options.animationSpeed); 441 } 442 }); 443 } 444 445 }; 446 447 $.fn.dockmodal = function (method) { 448 if (methods[method]) { 449 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 450 } else if (typeof method === 'object' || !method) { 451 return methods.init.apply(this, arguments); 452 } else { 453 $.error('Method ' + method + ' does not exist on jQuery.dockmodal'); 454 } 455 }; 456})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.