1/* 2JQuery plug-in to handle modals on MVC modules. 3It assumes existing markup as defined on MvcAdmin.Master or MvcFront.Master (It could be used custom in own view if needed nested modals). 4*/ 5 6$(function () { 7 (function ($) { 8 $.fn.cpModal = function (opt) { 9 //Here extends more options when needed modal with new behaviors LC. 10 var defaults = { 11 title: 'CP modal', // [html content] modal title's 12 url: '', // [string] URL to be loaded on modal 13 type: 'GET', // [string] type used for request (only in Ajax call. 'GET' or 'POST'). 14 contentType: 'application/x-www-form-urlencoded', // [string] contentType used for request (only in Ajax call). 15 data: null, // [Object/string] data used for request (only in Ajax call). 16 cache: false, // [bool] cache used for request (only in Ajax call). 17 htmlContent: '', // [html content] When url is empty, uses this as modal's content 18 className: '', // [string] CSS class for modal container 19 isFrontEnd: true, // [bool] Whether modal's border color will be displayed as front-end or not 20 parentWindowID: '', // [string] modal's parent window identifier (used for nested modals) 21 isNestedModal: false, // [bool] is this a nested modal 22 onClose: null, // [function] code to execute when close button is clicked 23 autoLoad: true, // [bool] load content when invoking plug-in 24 autoAdjust: false, // [bool] whether or not the modal will be auto positioned when scrolling 25 useIframe: false, // [bool] whether or not to use an iFrame to load content 26 iframeHeight: '', // [string] if using iframe, set specifc height for it (ex: '200px'). 27 elementID: null, //If a modal needs to be created with a custom ID, not using mvcModal as ID. 28 draggable: true, //Whether or not the modal is draggable. 29 insideEditor: false, //Whether or not the modal is opening inside editor, in case of slideshow within editor, for example. 30 showLoading: false, //Whether or not to show loading graphic while loading the modal. 31 async: false, //Whether or not to load asynchronously the html content (only if options.url is defined). 32 onLoadComplete: null, //[function] code to execute when the modal has loaded successfully from AJAX 33 scrolling: false, // [bool] whether iframe is scrollable. 34 verticalCenter: false 35 }; 36 37 var options = $.extend(defaults, opt); 38 // cache the base element 39 var base = this; 40 base.options = options; 41 // initialize (and localize) all variables 42 var $modal = ''; 43 var $parentWindow = (options.parentWindowID && options.parentWindowID != '') ? $('#' + options.parentWindowID) : $(window); 44 var triggeringElement = null; 45 46 // PUBLIC FUNCTIONS 47 this.init = function () { 48 $modal = $(this); 49 $modal.attr("role", "dialog"); 50 $modal.attr("aria-modal", "true"); 51 $modal.attr("tabindex", "-1"); 52 var titleId = (Math.random().toString(36)).slice(2); 53 $modal.attr("aria-labelledby", titleId); 54 55 // If this modal is appearing inside an iframe remove admin wrap which can cause some issues 56 if (window.self !== window.top) { 57 $modal.attr('style', function (i, s) { return s + 'height: auto !important;' }); 58 } 59 60 // Saves current jquery object reference for future references to call public methods if needed 61 if (!$modal.data('cpModal')) 62 $modal.data('cpModal', base); 63 64 // Sets modal title 65 var $modalTitle = $modal.find('.modalTitle').filter(":first"); 66 $modalTitle.html(options.title); 67 $modalTitle.attr("id", titleId); 68 // Sets modal close button event. 69 if (options.onClose != null) { 70 $modal.find('.modalClose').filter(":first").attr('onclick', '').unbind('click'); 71 $modal.find('.modalClose').filter(":first").bind("click", function (e) { 72 e.preventDefault(); 73 options.onClose(e, base); 74 var element = document.getElementsByClassName('modalTitle')[0] 75 var events = $._data(element, "events"); 76 if(events != undefined) 77 events.mouseout = undefined; 78 }); 79 } else { 80 $modal.find('.modalClose').filter(":first").attr('onclick', '').unbind('click'); 81 $modal.find('.modalClose').filter(":first").bind("click", function (e) { 82 e.preventDefault(); 83 base.hide(); 84 var element = document.getElementsByClassName('modalTitle')[0] 85 var events = $._data(element, "events"); 86 if(events != undefined) 87 events.mouseout = undefined; 88 return false; 89 });
90 } 91 92 $(".modalTitle").mouseout(function () { 93 $("body").trigger($.Event("mouseup", { which: 1 })); 94 }); 95 96 if ($.fn.draggable) { 97 if (!options.draggable) 98 $modal.css({ 'top': '', 'left': '' }); //reset to default position 99 if ($modal.data('draggable') && !options.draggable) { 100 $modal.draggable('destroy'); 101 $modalTitle.css('cursor', 'auto'); 102 } 103 if (!$modal.data('draggable') && options.draggable) { 104 $modal.draggable({ 105 handle: '.modalTitleLeft', 106 iframeFix: self !== top, 107 start: function (event, ui) { 108 } 109 }); 110 $modalTitle.css('cursor', 'move'); 111 } 112 } 113 114 // if needed, loads modal after initialization 115 if (options.autoLoad) 116 base.load(); 117 }; 118 119 this.load = function () { 120 if (options.useIframe) { 121 //create iframe on the fly 122 var iframeUrl = document.createElement('a'); 123 iframeUrl.href = options.url; 124 if (iframeUrl.protocol !== window.location.protocol || iframeUrl.host !== window.location.host) { 125 alert('Modal was incorrectly configured to display content.'); 126 return; 127 } 128 var $iframe = $('<iframe/>', { 129 'data-src': iframeUrl.pathname + iframeUrl.search + iframeUrl.hash, 130 id: 'iframeModal', 131 name: 'iframeModal', 132 frameborder: 0 133 }).css('border', 'none'); 134 if (options.iframeHeight) 135 $iframe.css('height', options.iframeHeight); 136 if (options.scrolling) 137 $iframe.css('overflow-y', 'auto'); 138 else 139 $iframe.attr('scrolling', 'no'); 140 $modal.find('.modalContent').filter(":first").html($iframe); 141 base.show(); 142 143 if (options.onLoadComplete != null) { 144 options.onLoadComplete(base); 145 } 146 } else if (options.url && options.url != '') { 147 var ignoreEditor = options.insideEditor; 148 //load from URL 149 $.ajax({
150 url: options.url, 151 type: options.type, 152 contentType: options.contentType, 153 data: options.data, 154 async: options.async, 155 ignoreEditor: ignoreEditor, 156 cache: options.cache, 157 success: function (result) { 158 var content = parseContent(result); 159 $modal.find('.modalContent').filter(":first").html(content.body); 160 $modal.find('.modalBottom').filter(":first").html(content.footer); 161 base.show(); 162 163 if (options.onLoadComplete != null) { 164 options.onLoadComplete(base); 165 } 166 }, 167 error: function (xhr, textStatus, exception) { 168 alert('Error encountered while loading modal.' + "\nStatus: " + xhr.status + "\n" + "Exception: " + exception); 169 $('#ajaxErrorLog').text(xhr.responseText); 170 }, 171 beforeSend: function () { 172 if (options.showLoading) 173 ajaxPostBackStart('Loading'); 174 }, 175 complete: function () { 176 if (options.showLoading) 177 ajaxPostBackEnd(); 178 } 179 }); 180 } else if (options.htmlContent && options.htmlContent != '') { 181 //Load specific content 182 var content = parseContent(options.htmlContent); 183 $modal.find('.modalContent').filter(":first").html(content.body); 184 $modal.find('.modalBottom').filter(":first").html(content.footer); 185 base.show(); 186 187 if (options.onLoadComplete != null) { 188 options.onLoadComplete(base); 189 } 190 } else { 191 alert('Modal was incorrectly configured to display content.'); 192 } 193 }; 194 195 this.show = function () { 196 if (options.useIframe) { 197 if (isie) { 198 window.frames['iframeModal'].document.location.href = $modal.find('iframe').attr('data-src'); // This method was required tp address issue in IE 9 with moving IFrames arund and javascript errors 199 } 200 } 201 202 if ($modal.hasClass('modalContainerCP') && options.isFrontEnd) { 203 $modal.removeClass('modalContainerCP'); 204 $modal.find('.modalContent').filter(":first").removeClass('adminWrap'); 205 } else if (!$modal.hasClass('modalContainerCP') && !options.isFrontEnd) { 206 $modal.addClass('modalContainerCP'); 207 $modal.find('.modalContent').filter(":first").addClass('adminWrap'); 208 } 209 210 if (options.useIframe && $modal.hasClass('noIframe')) { 211 $modal.removeClass('noIframe'); 212 } else if (!options.useIframe && !$modal.hasClass('noIframe')) { 213 $modal.addClass('noIframe'); 214 } 215 216 if (options.className && options.className != '') 217 $modal.addClass(options.className); 218 219 if (options.useIframe && window.self !== window.top) { //IFrame loaded inside IFrame 220 $modal.addClass('nestedIframe'); 221 } 222 223 if (options.autoAdjust) { 224 $(window).bind("scroll." + $modal.attr('id'), function () { 225 adjustPosition(); 226 }); 227 adjustPosition(); 228 } 229 230 if ($('.modalBackground').length == 0) { 231 //creates a modal background for the page on the fly
232 $('<div id="mvcModal_backgroundElement" class="modalBackground"></div>').prependTo('body'); 233 } 234 235 $(document).on("keydown.cpModal." + $modal.attr('id'), function (e) { 236 if (e.key === "Escape") { 237 base.hide(); 238 return; 239 } 240 241 if (e.key !== "Tab") { 242 return; 243 } 244 245 var $focusableElements = $modal.find('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])').filter(':visible'); 246 if ($focusableElements.length === 0) { 247 e.preventDefault(); 248 $modal.focus(); 249 return; 250 } 251 252 var first = $focusableElements.get(0); 253 var last = $focusableElements.get($focusableElements.length - 1); 254 255 if (e.shiftKey && document.activeElement === first) { 256 e.preventDefault(); 257 last.focus(); 258 } else if (!e.shiftKey && document.activeElement === last) { 259 e.preventDefault(); 260 first.focus(); 261 } 262 }); 263 264 $modal.show(); 265 triggeringElement = document.activeElement; 266 267 var $initialFocusableElement = $modal.find('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])') 268 .filter(':visible') 269 .first(); 270 271 if ($initialFocusableElement.length > 0) { 272 $initialFocusableElement.get(0).focus({ preventScroll: true }); 273 } else { 274 $modal.get(0).focus({ preventScroll: true }); 275 } 276 277 if (!isie) { 278 $modal.find('iframe').attr('src', $modal.find('iframe').attr('data-src')); 279 } 280 if (!options.autoAdjust || !options.verticalCenter) 281 window.CommonPopoverInstance.resizeToWindow($modal); 282 283 $(window).unbind('resize orientationChanged', setModalHeightWidthToFull).bind('resize orientationChanged', setModalHeightWidthToFull); 284 285 setModalHeightWidthToFull($modal); 286 287 $('.modalBackground').show(); //TODO: How to handle this better for nested modals 288 289 options.verticalCenter && verticalCenter($modal); 290 }; 291 292 function verticalCenter($modal) { 293 parent = window; 294 $modal.css({ 295 "position": "absolute", 296 "top": ((($(parent).height() - $modal.outerHeight()) / 2) + $(parent).scrollTop() + "px"), 297 "left": ((($(parent).width() - $modal.outerWidth()) / 2) + $(parent).scrollLeft() + "px") 298 }); 299 } 300 301 this.hide = function () { 302 $modal.hide(); 303 $modal.removeClass(options.className); 304 $(window).unbind("scroll." + $modal.attr('id')); 305 $(window).unbind('resize orientationChanged', setModalHeightWidthToFull); 306 var $visibleModals = $('.modalContainer:visible, .modalContainerCP:visible'); 307 var hasOpenNestedModals = $visibleModals.length > 0; 308 if (!options.isNestedModal || !hasOpenNestedModals) 309 $('.modalBackground').hide(); //TODO: How to handle this better for nested modals 310 $(document).off("keydown.cpModal." + $modal.attr('id')); 311 triggeringElement?.focus(); 312 }; 313 314 this.destroy = function () { 315 //TODO: This needs more work 316 $modal.data('cpModal').remove(); 317 $(document).off("keydown.cpModal." + $modal.attr('id')); 318 }; 319 320 // PRIVATE FUNCTIONS 321 322 function adjustPosition() { 323 var top = (($parentWindow.height() - $modal.outerHeight(false)) / 2) + $parentWindow.scrollTop(); 324 if (top < 0) // do not tolerate negative on top position. 325 top = 0; 326 $modal.css({ "top": top + "px" }); 327 /* Not needed since left position is managed with styles and it works fine for nested modals too. 328 if (options.isNestedModal) 329 $modal.css({ "left": (($parentWindow.width() - $modal.outerWidth()) / 2) + $parentWindow.scrollLeft() + "px" });*/ 330 } 331 332 /*This is used to adjust the modal when the users screen view is smaller than the modal. -Zach Terwort*/ 333 var lastScroll = 0; 334 $(window).scroll(function () { 335 var top = $parentWindow.height() - $modal.outerHeight(false); 336 var scrollDirection = $parentWindow.scrollTop(); 337 if (top < 0 && scrollDirection > lastScroll) { 338 top = $parentWindow.height() - $modal.height() - 20; 339 $modal.css({ "top": top + "px" }); 340 } 341 else if (top < 0) { 342 top = 20; 343 $modal.css({ "top": top + "px" }); 344 } 345 lastScroll = scrollDirection; 346 }); 347 348 /*This is used to make sure the modal isn't off the screen, and inaccessible after the user drops the modal. -Zach Terwort */ 349 $(document).mouseup(function (event) { 350 var top = $modal.position().top; 351 if (top < 0) { 352 top = 20; 353 $modal.css({ "top": top + "px" }); 354 } 355 }); 356 357 function parseContent(htmlContent) { 358 htmlContent = htmlContent || ''; 359 var content = { body: htmlContent, footer: '' }; 360 var indexFooter = htmlContent.indexOf('<modalfooter>'); 361 if (indexFooter != -1) { 362 content.body = htmlContent.substr(0, indexFooter);
363 content.footer = htmlContent.substr(indexFooter).replace('<modalfooter>', '').replace('</modalfooter>', ''); 364 } 365 return content; 366 } 367 368 function setModalHeightWidthToFull() { 369 var viewportHeight = $(window).height(); 370 var maxHeight = viewportHeight - 140; 371 if (maxHeight <= $modal.height() && $(document.body).hasClass('wide')) { 372 $('.modalContentRight > .modalContent', $modal).css('max-height', maxHeight + 'px'); 373 $modal.addClass('fullHeight'); 374 } 375 else { 376 $('.modalContentRight > .modalContent', $modal).css('max-height', ''); 377 $modal.removeClass('fullHeight'); 378 } 379 380 if ($(document.body).hasClass('wide') && $modal.hasClass('fullWidth')) { 381 $modal.removeClass('fullWidth'); 382 $modal.css('margin-top', ''); 383 } 384 } 385 386 base.init(); 387 return this; 388 }; 389 })(jQuery); 390}); 391 392//Standard function to open modals in most of the scenarios 393function openCpModal(options) { 394 //override modal options for mobile view 395 if ($('#IsMobile').val() == 'True') { 396 var mobileOptions = { 397 autoAdjust: false //do not autoadjust when is mobile view. Modal nneds to be accessed from small browser in one spot. 398 }; 399 options = $.extend(mobileOptions, options); 400 if (options.className == null || options.className.indexOf('mobile') < 0) 401 options.className = options.className + ' mobile'; //if needed add mobile class to modal. 402 } 403 404 var $modal = getCommonCpModal(options.elementID); 405 if ($modal.parent() != $('body')) 406 $modal.appendTo('body'); //if needed move at the end of the body 407 408 if ($.fn.cpModal === undefined) { //Multiple versions of Jquery causing fn not to be registered. 409 $.getScript('/Assets/Scripts/Modal.js', function () { return $modal.cpModal(options); }); 410 } else { 411 return $modal.cpModal(options); 412 } 413} 414 415//Standard function to close modals in most of the sceneries 416function closeCpModal() { 417 if (getCommonCpModal().data('cpModal')) { 418 return getCommonCpModal().data('cpModal').hide(); 419 } 420} 421 422//Get markup modal or create one on the fly if needed 423function getCommonCpModal(elementID) { 424 //If elementID is not provided, use the default 'mvcModal' id. 425 if (elementID == null) 426 elementID = 'mvcModal'; 427 //If the element already exists on the page, simply return the element to be reused. 428 if ($('#' + elementID).length > 0) { 429 return $('#' + elementID); 430 } 431 else { 432 //Create on the fly a common mvc modal markup with custom ID.
433 var $modalContainer = $('<div id="' + elementID + '" class="modalContainer modalContainerCP MVC noIframe" style="display: none;"></div>'); 434 var $modalTitleLeft = $('<div class="modalTitleLeft"><h3 class="modalTitle"></h3><a class="modalClose" href="#" aria-label="Close this modal" title="Close this window">' + 435 '<svg viewBox="0 0 25 25" id="modalIconClose"><polygon style="fill:currentcolor" points="18.806,6.98 18.075,6.248 12.532,11.792 6.989,6.248 6.257,6.98 11.786,12.508 6.212,18.084 6.943,18.815 12.532,13.224 18.12,18.815 18.851,18.084 13.277,12.508"></polygon>' + 436 '</svg></a></div>'); 437 var $modalContentLeft = $('<div class="modalContentLeft"><div class="modalContentRight"><div class="newCP adminWrap modalContent"></div></div></div>'); 438 var $modalBottomLeft = $('<div class="modalBottomLeft"><div class="modalBottomRight"><div class="modalBottom"></div></div></div>'); 439 $modalContainer.append($modalTitleLeft).append($modalContentLeft).append($modalBottomLeft); 440 $modalContainer.appendTo('body'); 441 return $modalContainer; 442 } 443} 444 445function PositionVerticle($modal) { 446 $modal.css({ "top": (($(window).height() - $modal.outerHeight(false)) / 2) + $(window).scrollTop() + "px" }); 447 $modal.css({ "top": ($parentWindow.height() - $modal.outerHeight(false)) / 2 + $parentWindow.scrollTop() + "px" }); 448} 449 450function showModal(className) { 451 var $modal = $('.modalContainer.' + className); 452 window.onscroll = function () { 453 PositionVerticle($modal); 454 }; 455 PositionVerticle($modal); 456 $modal.show(); 457 $(window).unbind('resize orientationChanged', setModalHeightWidthToFull).bind('resize orientationChanged', setModalHeightWidthToFull); 458 setModalHeightWidthToFull($modal); 459 $('.modalBackground').show(); 460} 461 462function hideModal(className) { 463 $('.modalContainer.' + className).hide(); 464 $('.modalBackground').hide(); 465} 466 467function hideModalAndReloadPage(className) { 468 hideModal(className); 469 location.reload(true); 470} 471 472/* 473JQuery plug-in to handle popovers. 474 475*/ 476function CommonPopoverClass() { 477 this.popovers = []; 478 this.initialized = false; 479 this.$commonPopup = null; 480 481 this.PopoverWrap = function ($popover, options) { 482 this.ID = $popover.attr('id'); 483 this.$popoverContent = $popover.children(); 484 this.isVisible = false; 485 this.options = options; 486 this.onClose = null; 487 }; 488} 489 490CommonPopoverClass.prototype.hideAll = function (animate) { 491 var self = this; 492 if (self.$commonPopup != null) { 493 self.$commonPopup.fadeOut(animate ? 300 : 0, function () { 494 for (var i = 0; i < self.popovers.length; i++) { 495 if (self.popovers[i].options.className && self.popovers[i].options.className != '') 496 self.$commonPopup.removeClass(self.popovers[i].options.className); 497 self.popovers[i].isVisible = false; 498 } 499 }); 500 } 501}; 502 503CommonPopoverClass.prototype.show = function (popoverWrap) { 504 var self = this; 505 var alreadyOpened = false; //To prevent creating animation if popover is already opened 506 for (var i = 0; i < self.popovers.length; i++) { 507 if (self.popovers[i].options.className) 508 self.$commonPopup.removeClass(self.popovers[i].options.className); 509 if (self.popovers[i].isVisible) 510 alreadyOpened = true; 511 self.popovers[i].isVisible = false; 512 } 513 self.$commonPopup.children().detach(); 514 self.$commonPopup.append(popoverWrap.$popoverContent); 515 516 if (popoverWrap.options.className) { 517 self.$commonPopup.addClass(popoverWrap.options.className); 518 window.setTimeout(function () { 519 self.$commonPopup.addClass(popoverWrap.options.className); 520 }, 0); 521 } 522 523 popoverWrap.isVisible = true; 524 self.$commonPopup.fadeIn(alreadyOpened ? 0 : 300, function () { 525 //If needed call back onOpen event 526 if (popoverWrap.options.onOpen != null && typeof (popoverWrap.options.onOpen) == "function") 527 popoverWrap.options.onOpen(popoverWrap); 528 }); 529}; 530 531CommonPopoverClass.prototype.hide = function (popoverWrap) { 532 var self = this; 533 if (popoverWrap && popoverWrap.options) { 534 self.$commonPopup.fadeOut(300, function () { 535 if (popoverWrap.options.className) 536 self.$commonPopup.removeClass(popoverWrap.options.className); 537 popoverWrap.isVisible = false; 538 }); 539 } 540}; 541
542CommonPopoverClass.prototype.RegisterPopover = function ($popover, options) { 543 var self = this; 544 if ($popover.attr('id') == null || $popover.attr('id') == "") { 545 $.ajaxSetup({ async: false }); 546 AJAX("/Utility/NewGuid", "post", null, function (reponse) { 547 $popover.attr('id', reponse.Guid); 548 }, false); 549 $.ajaxSetup({ async: true }); 550 } 551 552 //Creates popover wrapper 553 var newPopoverWrap = new self.PopoverWrap($popover, options); 554 //remove popover if nedded 555 self.RemovePopover(newPopoverWrap); 556 //add popover to global array 557 self.popovers.push(newPopoverWrap); 558 559 //common popover initialization if needed 560 self.init(); 561 562 //pop over specific initialization 563 564 // Sets popover close button event. 565 if (options.onClose != null && typeof (options.onClose) == "function") { 566 $popover.find('.cpClosePopOver').filter(":first").attr('onclick', '').unbind('click'); 567 $popover.find('.cpClosePopOver').filter(":first").bind("click", function (e) { 568 options.onClose(e, newPopoverWrap); 569 }); 570 } else { 571 $popover.find('.cpClosePopOver').filter(":first").attr('onclick', '').unbind('click'); 572 $popover.find('.cpClosePopOver').filter(":first").bind("click", function (e) { 573 e.preventDefault(); 574 self.hide(newPopoverWrap); 575 }); 576 } 577 578 return newPopoverWrap; 579}; 580 581CommonPopoverClass.prototype.RemovePopover = function (popoverWrap) { 582 var self = this; 583 for (var i = 0; i < self.popovers.length; i++) { 584 if (self.popovers[i].ID == popoverWrap.ID) 585 self.popovers.splice(i); 586 } 587}; 588 589CommonPopoverClass.prototype.init = function () { 590 var self = this; 591 if (!self.initialized) { 592 self.$commonPopup = self.getCommonPopover(); 593 594 self.$commonPopup.click(function (e) { 595 e.stopPropagation(); 596 }).draggable({ 597 handle: '.cpPopOverHeader' 598 }); 599 600 $('html').click(function () { 601 self.hideAll(true); 602 }); 603 604 self.initialized = true; 605 } 606}; 607 608CommonPopoverClass.prototype.getCommonPopover = function (elementID) { 609 var commonElementID = "cpCommonPopover"; 610 if (elementID == null) { 611 if ($('#cpCommonPopover').length == 1) 612 return $('#cpCommonPopover'); 613 if ($('.cpPopOver.common').length == 1) 614 return $('.cpPopOver.common'); 615 } 616 else 617 commonElementID = elementID; 618 //create on the fly a common popover markup. 619 //Sets initial top position based on toolbar if exists 620 var topPosition = ""; 621 if ($("#divToolbars").length > 0) { 622 topPosition = " top: " + ($("#divToolbars").height() + $('div.cp-Toolbars').height() + 30) + "px;"; 623 } 624 625 var $commonPopover = $("<div id=\"" + commonElementID + "\" class=\"cpPopOver common\" style=\"display: none; z-index:100; position:fixed;" + topPosition + "\"></div>"); 626 return $commonPopover.appendTo('body'); 627}; 628 629(function ($) { 630 $.fn.cpPopover = function (opt) { 631 //Here extends more options when needed popover with new behaviors LC. 632 var defaults = { 633 url: '', // [string] URL to be loaded on popover 634 type: 'GET', // [string] type used for request (only in Ajax call. 'GET' or 'POST'). 635 contentType: 'application/x-www-form-urlencoded', // [string] contentType used for request (only in Ajax call). 636 data: null, // [Object/string] data used for request (only in Ajax call). 637 cache: false, // [bool] cache used for request (only in Ajax call). 638 htmlContent: '', // [html content] When url is empty, uses this as popover's content 639 onClose: null, // [function] code to execute when close button is clicked 640 onOpen: null, // [function] code to execute when popover is opened 641 onInit: null, // [function] code to execute when popover is initialized (after loading) 642 className: '', // [string] CSS class for popover container 643 makeAjaxCallEverytime: false //Whether or not an ajax call is always made whenever the control is clicked. If false, uses the cached(already rendered) version. 644 }; 645 646 var options = $.extend(defaults, opt); 647 648 // cache the base element 649 var base = this; 650 // initialize (and localize) all variables 651 var $handler = null; 652 var $popover = null; 653 var popoverWrapper = null; 654 655 // PUBLIC FUNCTIONS 656 this.init = function () { 657 $handler = $(this); 658 $popover = $handler.nextAll("div.cpPopOver"); 659 660 // Saves current jquery object reference for future references to call public methods if needed 661 if (!$handler.data('cpPopover')) 662 $handler.data('cpPopover', base); 663 664 $handler.unbind("click.cpPopover").bind("click.cpPopover", function (e) { 665 e.preventDefault(); 666 e.stopPropagation(); 667 if ($popover.length == 0 || options.makeAjaxCallEverytime) { 668 //if popup has not being rendered yet, loaded it only first time 669 base.load(); 670 } else { 671 //toggle display
672 base.toggle(); 673 } 674 }); 675 676 if ($popover.length != 0) { 677 base.initPopOver(); 678 } 679 }; 680 681 this.initPopOver = function () { 682 $popover = $handler.nextAll("div.cpPopOver"); 683 684 //Register popover and store wrap reference 685 popoverWrapper = window.CommonPopoverInstance.RegisterPopover($popover, options); 686 687 //If needed call back onInit event 688 if (options.onInit != null && typeof (options.onInit) == "function") 689 options.onInit(popoverWrapper); 690 }; 691 692 this.load = function () { 693 if (options.url && options.url != '') { 694 //load from URL 695 $.ajax({ 696 url: options.url, 697 type: options.type, 698 contentType: options.contentType, 699 data: options.data, 700 async: false, 701 cache: options.cache, 702 success: function (response) { 703 if (response.ErrorMessage) { 704 alert(response.ErrorMessage); 705 } 706 else { 707 $handler.after(response); 708 base.initPopOver(); 709 base.show(); 710 } 711 }, 712 error: function (xhr, textStatus, exception) { 713 alert('Error encountered while loading popover.' + "\nStatus: " + xhr.status + "\n" + "Exception: " + exception); 714 $('#ajaxErrorLog').text(xhr.responseText); 715 } 716 }); 717 } else if (options.htmlContent && options.htmlContent != '') { 718 //Load specific content //TOOD: ???? 719 $handler.after(options.htmlContent); 720 base.initPopOver(); 721 base.show(); 722 } else { 723 alert('Popover was incorrectly configured to display content.'); 724 } 725 }; 726 727 this.show = function () { 728 window.CommonPopoverInstance.show(popoverWrapper); 729 }; 730 731 this.hide = function () { 732 window.CommonPopoverInstance.hide(popoverWrapper); 733 }; 734 735 this.toggle = function () { 736 if (popoverWrapper.isVisible) 737 base.hide(); 738 else 739 base.show(); 740 }; 741 742 this.destroy = function () { 743 if ($popover.length != 0) { 744 $popover.find('.cpClosePopOver').filter(":first").unbind('click'); 745 $popover.unbind("click"); 746 if($popover.data('draggable')) 747 $popover.draggable('destroy'); 748 window.CommonPopoverInstance.RemovePopover(popoverWrapper); 749 $popover.remove(); 750 } 751 $handler.unbind("click.cpPopover"); 752 $handler.removeData('cpPopover'); 753 }; 754 755 // PRIVATE FUNCTIONS 756 757 base.init(); 758 return this; 759 }; 760})(jQuery); 761 762$(function () { 763 if (!window.CommonPopoverInstance) { 764 window.CommonPopoverInstance = new CommonPopoverClass(); 765 } 766}); 767 768CommonPopoverClass.prototype.resizeToWindow = function ($popup) { 769 var viewportHeight = $(window).height(); 770 var toolbarHeight = ($('#divToolbars').height() + $('div.cp-Toolbars').height()); 771 var maxHeight = viewportHeight - toolbarHeight - 205; 772 var popupHeight = $popup.height(); 773 var popupOffset = $popup.offset(); 774 var scrollTop = $popup.scrollTop(); 775 var pageScroll = getPageScroll(); 776 $popup.find('.cpTabPanel').css('max-height', maxHeight + 'px'); 777 $popup.css('top', 20 + 'px'); //This always needs to have a top. So we set it here. 778}; 779 780function getPageScroll() { 781 var xScroll, yScroll; 782 if (self.pageYOffset) { 783 yScroll = self.pageYOffset; 784 xScroll = self.pageXOffset; 785 } else if (document.documentElement && document.documentElement.scrollTop) { 786 yScroll = document.documentElement.scrollTop; 787 xScroll = document.documentElement.scrollLeft; 788 } else if (document.body) {// all other Explorers 789 yScroll = document.body.scrollTop; 790 xScroll = document.body.scrollLeft; 791 } 792 return new Array(xScroll, yScroll); 793} 794 795// Adapted from getPageSize() by quirksmode.com 796function getPageHeight() { 797 var windowHeight; 798 if (self.innerHeight) { // all except Explorer 799 windowHeight = self.innerHeight; 800 } else if (document.documentElement && document.documentElement.clientHeight) { 801 windowHeight = document.documentElement.clientHeight; 802 } else if (document.body) { // other Explorers 803 windowHeight = document.body.clientHeight; 804 } 805 return windowHeight; 806}
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.