1;(function(window) { 2 3"use strict"; 4 5if (BX.PopupWindowManager) 6{ 7 return; 8} 9 10BX.PopupWindowManager = 11{ 12 _popups : [], 13 _currentPopup : null, 14 15 create : function(uniquePopupId, bindElement, params) 16 { 17 var index = -1; 18 if ((index = this._getPopupIndex(uniquePopupId)) !== -1) 19 { 20 return this._popups[index]; 21 } 22 23 var popupWindow = new BX.PopupWindow(uniquePopupId, bindElement, params); 24 BX.addCustomEvent(popupWindow, "onPopupShow", BX.delegate(this.onPopupShow, this)); 25 BX.addCustomEvent(popupWindow, "onPopupClose", BX.delegate(this.onPopupClose, this)); 26 27 return popupWindow; 28 }, 29 30 onPopupWindowIsInitialized : function(uniquePopupId, popupWindow) 31 { 32 BX.addCustomEvent(popupWindow, "onPopupDestroy", BX.delegate(this.onPopupDestroy, this)); 33 this._popups.push(popupWindow); 34 }, 35 36 onPopupShow : function(popupWindow) 37 { 38 if (this._currentPopup !== null) 39 { 40 this._currentPopup.close(); 41 } 42 43 this._currentPopup = popupWindow; 44 }, 45 46 onPopupClose : function(popupWindow) 47 { 48 this._currentPopup = null; 49 }, 50 51 onPopupDestroy : function(popupWindow) 52 { 53 var index; 54 if ((index = this._getPopupIndex(popupWindow.uniquePopupId)) !== -1) 55 { 56 this._popups = BX.util.deleteFromArray(this._popups, index); 57 } 58 }, 59 60 getCurrentPopup : function() 61 { 62 return this._currentPopup; 63 }, 64 65 isPopupExists : function(uniquePopupId) 66 { 67 return this._getPopupIndex(uniquePopupId) !== -1 68 }, 69 70 _getPopupIndex : function(uniquePopupId) 71 { 72 var index = -1; 73 74 for (var i = 0; i < this._popups.length; i++) 75 { 76 if (this._popups[i].uniquePopupId === uniquePopupId) 77 { 78 return i; 79 } 80 } 81 82 return index; 83 }, 84 85 getMaxZIndex : function() 86 { 87 var zIndex = 0, ii; 88 for (ii = 0; ii < this._popups.length; ii++) 89 { 90 zIndex = Math.max(zIndex, this._popups[ii].params.zIndex); 91 } 92 return zIndex; 93 } 94}; 95BX.addCustomEvent("onPopupWindowIsInitialized", BX.proxy(BX.PopupWindowManager.onPopupWindowIsInitialized, BX.PopupWindowManager)); 96/** 97 * 98 * @param {string} uniquePopupId 99 * @param {Element|object|null} bindElement 100 * @param params 101 * @constructor 102 */ 103BX.PopupWindow = function(uniquePopupId, bindElement, params) 104{ 105 params = params || {}; 106 this.params = params; 107 108 BX.onCustomEvent("onPopupWindowInit", [uniquePopupId, bindElement, params]); 109 110 this.uniquePopupId = uniquePopupId; 111 112 this.params.zIndex = parseInt(params.zIndex); 113 this.params.zIndex = isNaN(params.zIndex) ? 0 : params.zIndex; 114 this.buttons = params.buttons && BX.type.isArray(params.buttons) ? params.buttons : []; 115 this.offsetTop = BX.PopupWindow.getOption("offsetTop"); 116 this.offsetLeft = BX.PopupWindow.getOption("offsetLeft"); 117 this.firstShow = false; 118 this.bordersWidth = 20; 119 this.bindElementPos = null; 120 this.closeIcon = null; 121 this.resizeIcon = null; 122 this.angle = null; 123 this.overlay = null; 124 this.titleBar = null; 125 this.bindOptions = typeof(params.bindOptions) === "object" ? params.bindOptions : {}; 126 this.autoHide = params.autoHide === true; 127 this.isAutoHideBinded = false; 128 this.closeByEsc = params.closeByEsc === true; 129 this.isCloseByEscBinded = false; 130 131 this.width = null; 132 this.height = null; 133 this.minWidth = 0; 134 this.minHeight = 0; 135 136 if (params.parentPopup instanceof BX.PopupWindow) 137 { 138 this.parentPopup = params.parentPopup; 139 this.appendContainer = params.parentPopup.contentContainer; 140 141 params.offsetTop = (params.offsetTop? params.offsetTop: 0) - (BX.PopupWindow.fullscreenStatus? 0: this.parentPopup.popupContainer.offsetTop); 142 params.offsetLeft = (params.offsetLeft? params.offsetLeft: 0) - (BX.PopupWindow.fullscreenStatus? 0: this.parentPopup.popupContainer.offsetLeft); 143 } 144 else 145 { 146 this.parentPopup = null; 147 this.appendContainer = document.body; 148 } 149 150 this.dragOptions = { 151 cursor: "", 152 callback: BX.DoNothing, 153 eventName: "" 154 }; 155 this.dragged = false; 156 this.dragPageX = 0; 157 this.dragPageY = 0; 158 159 if (params.events) 160 { 161 for (var eventName in params.events) 162 { 163 BX.addCustomEvent(this, eventName, params.events[eventName]); 164 } 165 } 166 167 var popupClassName = "popup-window"; 168 169 /*if (params.lightShadow) 170 popupClassName += " popup-window-light";*/ 171 172 if (params.contentColor && BX.type.isNotEmptyString(params.contentColor)) 173 { 174 popupClassName += " popup-window-content-" + params.contentColor; 175 } 176 177 if (params.contentNoPaddings) 178 { 179 popupClassName += " popup-window-content-no-paddings"; 180 } 181 182 if (params.noAllPaddings) 183 { 184 popupClassName += " popup-window-no-paddings"; 185 } 186 187 if (params.titleBar) 188 { 189 popupClassName += " popup-window-with-titlebar"; 190 } 191 192 if (params.className && BX.type.isNotEmptyString(params.className)) 193 { 194 popupClassName += " " + params.className; 195 } 196 197 if (params.darkMode) 198 { 199 popupClassName += ' popup-window-dark'; 200 } 201 202 this.popupContainer = document.createElement("div"); 203 var titleBarID = "popup-window-titlebar-" + uniquePopupId; 204 205 if(params.titleBar) 206 { 207 this.titleBar = BX.create("div", { 208 props : { 209 className: "popup-window-titlebar", 210 id: titleBarID 211 } 212 }); 213 } 214 215 if (params.closeIcon) 216 { 217 this.closeIcon = BX.create("span", { 218 props : { className: "popup-window-close-icon" + (params.titleBar ? " popup-window-titlebar-close-icon" : "") }, 219 style : (typeof(params.closeIcon) === "object" ? params.closeIcon : {} ), 220 events : { click : BX.proxy(this._onCloseIconClick, this) } 221 }); 222 223 if (BX.browser.IsIE()) 224 { 225 BX.adjust(this.closeIcon, { attrs: { hidefocus: "true" } }); 226 } 227 } 228 229 this.contentContainer = BX.create("div",{ 230 props:{ 231 id: "popup-window-content-" + uniquePopupId, 232 className: "popup-window-content" 233 } 234 }); 235 236 BX.adjust(this.popupContainer, { 237 props : { 238 id : uniquePopupId, 239 className : popupClassName 240 }, 241 style : { 242 zIndex: this.getZindex(), 243 position: "absolute", 244 display: "none", 245 top: "0px", 246 left: "0px" 247 }, 248 children : [this.titleBar, this.contentContainer, this.closeIcon] 249 }); 250 251 this.appendContainer.appendChild(this.popupContainer); 252 253 this.buttonsContainer = null; 254 255 if (params.angle) 256 { 257 this.setAngle(params.angle); 258 } 259 260 if (params.overlay) 261 { 262 this.setOverlay(params.overlay); 263 } 264 265 this.setOffset(params); 266 this.setBindElement(bindElement); 267 this.setTitleBar(params.titleBar); 268 this.setContent(params.content); 269 this.setButtons(params.buttons); 270 this.setWidth(params.width); 271 this.setHeight(params.height); 272 this.setResizeMode(params.resizable); 273 274 if (params.bindOnResize !== false) 275 { 276 BX.bind(window, "resize", BX.proxy(this._onResizeWindow, this)); 277 } 278 BX.onCustomEvent("onPopupWindowIsInitialized", [uniquePopupId, this]); 279}; 280 281/** 282 * 283 * @param {Element|string} content 284 */ 285BX.PopupWindow.prototype.setContent = function(content) 286{ 287 if (!this.contentContainer || !content) 288 { 289 return; 290 } 291 292 if (BX.type.isElementNode(content)) 293 { 294 BX.cleanNode(this.contentContainer); 295 this.contentContainer.appendChild(content.parentNode ? content.parentNode.removeChild(content) : content ); 296 content.style.display = "block"; 297 } 298 else if (BX.type.isString(content)) 299 { 300 this.contentContainer.innerHTML = content; 301 } 302 else 303 { 304 this.contentContainer.innerHTML = " "; 305 } 306}; 307 308/** 309 * 310 * @param {BX.PopupWindowButton[]} buttons 311 */ 312BX.PopupWindow.prototype.setButtons = function(buttons) 313{ 314 this.buttons = buttons && BX.type.isArray(buttons) ? buttons : []; 315 316 if (this.buttonsContainer) 317 { 318 BX.remove(this.buttonsContainer); 319 } 320 321 if (this.buttons.length > 0 && this.contentContainer) 322 { 323 var newButtons = []; 324 for (var i = 0; i < this.buttons.length; i++) 325 { 326 var button = this.buttons[i]; 327 if (button === null || !BX.is_subclass_of(button, BX.PopupWindowButton)) 328 { 329 continue; 330 } 331 332 button.popupWindow = this; 333 newButtons.push(button.render()); 334 } 335 336 this.buttonsContainer = this.contentContainer.parentNode.appendChild( 337 BX.create("div",{ 338 props : { className : "popup-window-buttons" }, 339 children : newButtons 340 }) 341 ); 342 } 343}; 344 345/** 346 * 347 * @returns {BX.PopupWindowButton[]} 348 */ 349BX.PopupWindow.prototype.getButtons = function() 350{ 351 return this.buttons; 352}; 353 354/** 355 * 356 * @param {string} id 357 * @returns {BX.PopupWindowButton} 358 */ 359BX.PopupWindow.prototype.getButton = function(id) 360{ 361 for (var i = 0; i < this.buttons.length; i++) 362 { 363 var button = this.buttons[i]; 364 if (button.getId() === id) 365 { 366 return button; 367 } 368 } 369 370 return null; 371}; 372 373/** 374 * 375 * @param {Element|Event|object} bindElement 376 */ 377BX.PopupWindow.prototype.setBindElement = function(bindElement) 378{ 379 if (!bindElement || typeof(bindElement) !== "object") 380 { 381 return; 382 } 383
384 if (BX.type.isDomNode(bindElement) || (BX.type.isNumber(bindElement.top) && BX.type.isNumber(bindElement.left))) 385 { 386 this.bindElement = bindElement; 387 } 388 else if (BX.type.isNumber(bindElement.clientX) && BX.type.isNumber(bindElement.clientY)) 389 { 390 BX.fixEventPageXY(bindElement); 391 this.bindElement = { left : bindElement.pageX, top : bindElement.pageY, bottom : bindElement.pageY }; 392 } 393}; 394 395/** 396 * 397 * @param bindElement 398 * @returns {object} position 399 */ 400BX.PopupWindow.prototype.getBindElementPos = function(bindElement) 401{ 402 if (BX.type.isDomNode(bindElement)) 403 { 404 return BX.pos(bindElement, false); 405 } 406 else if (bindElement && typeof(bindElement) === "object") 407 { 408 if (!BX.type.isNumber(bindElement.bottom)) 409 { 410 bindElement.bottom = bindElement.top; 411 } 412 413 return bindElement; 414 } 415 else 416 { 417 var windowSize = BX.GetWindowInnerSize(); 418 var windowScroll = BX.GetWindowScrollPos(); 419 var popupWidth = this.popupContainer.offsetWidth; 420 var popupHeight = this.popupContainer.offsetHeight; 421 422 this.bindOptions.forceTop = true; 423 424 return { 425 left : windowSize.innerWidth/2 - popupWidth/2 + windowScroll.scrollLeft, 426 top : windowSize.innerHeight/2 - popupHeight/2 + windowScroll.scrollTop, 427 bottom : windowSize.innerHeight/2 - popupHeight/2 + windowScroll.scrollTop, 428 429 //for optimisation purposes 430 windowSize : windowSize, 431 windowScroll : windowScroll, 432 popupWidth : popupWidth, 433 popupHeight : popupHeight 434 }; 435 } 436}; 437 438/** 439 * 440 * @param {Object|bool} params 441 * @param {number} [params.offset = 0] 442 * @param {string} [params.position = "top"] 443 */ 444BX.PopupWindow.prototype.setAngle = function(params) 445{ 446 if (params === false && this.angle !== null) 447 { 448 BX.remove(this.angle.element); 449 this.angle = null; 450 return; 451 } 452 453 var className = "popup-window-angly"; 454 if (this.angle === null) 455 { 456 var position = this.bindOptions.position && this.bindOptions.position === "top" ? "bottom" : "top"; 457 var angleMinLeft = BX.PopupWindow.getOption(position === "top" ? "angleMinTop" : "angleMinBottom"); 458 var defaultOffset = BX.type.isNumber(params.offset) ? params.offset : 0; 459 460 var angleLeftOffset = BX.PopupWindow.getOption("angleLeftOffset", null); 461 if (defaultOffset > 0 && BX.type.isNumber(angleLeftOffset)) 462 { 463 defaultOffset += angleLeftOffset - BX.PopupWindow.defaultOptions.angleLeftOffset; 464 } 465 466 this.angle = { 467 element : BX.create("div", { props : { className: className + " " + className +"-" + position }}), 468 position : position, 469 offset : 0, 470 defaultOffset : Math.max(defaultOffset, angleMinLeft) 471 //Math.max(BX.type.isNumber(params.offset) ? params.offset : 0, angleMinLeft) 472 }; 473 474 this.popupContainer.appendChild(this.angle.element); 475 } 476 477 if (typeof(params) === "object" && params.position && BX.util.in_array(params.position, ["top", "right", "bottom", "left", "hide"])) 478 { 479 BX.removeClass(this.angle.element, className + "-" + this.angle.position); 480 BX.addClass(this.angle.element, className + "-" + params.position); 481 this.angle.position = params.position; 482 } 483 484 if (typeof(params) === "object" && BX.type.isNumber(params.offset)) 485 { 486 var offset = params.offset; 487 var minOffset, maxOffset; 488 if (this.angle.position === "top") 489 { 490 minOffset = BX.PopupWindow.getOption("angleMinTop"); 491 maxOffset = this.popupContainer.offsetWidth - BX.PopupWindow.getOption("angleMaxTop"); 492 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 493 494 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 495 this.angle.element.style.left = this.angle.offset + "px"; 496 this.angle.element.style.marginLeft = 0; 497 } 498 else if (this.angle.position === "bottom") 499 { 500 minOffset = BX.PopupWindow.getOption("angleMinBottom"); 501 maxOffset = this.popupContainer.offsetWidth - BX.PopupWindow.getOption("angleMaxBottom"); 502 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 503 504 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 505 this.angle.element.style.marginLeft = this.angle.offset + "px"; 506 this.angle.element.style.left = 0; 507 } 508 else if (this.angle.position === "right") 509 { 510 minOffset = BX.PopupWindow.getOption("angleMinRight"); 511 maxOffset = this.popupContainer.offsetHeight - BX.PopupWindow.getOption("angleMaxRight"); 512 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 513 514 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 515 this.angle.element.style.top = this.angle.offset + "px"; 516 } 517 else if (this.angle.position === "left") 518 { 519 minOffset = BX.PopupWindow.getOption("angleMinLeft"); 520 maxOffset = this.popupContainer.offsetHeight - BX.PopupWindow.getOption("angleMaxLeft"); 521 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 522 523 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 524 this.angle.element.style.top = this.angle.offset + "px"; 525 } 526 } 527}; 528 529/** 530 * 531 * @param {number} width 532 */ 533BX.PopupWindow.prototype.setWidth = function(width) 534{ 535 if (BX.type.isNumber(width) && width >= 0) 536 { 537 this.width = width; 538 this.contentContainer.style.width = width + "px"; 539 this.contentContainer.style.overflowX = "auto"; 540 if (this.titleBar) 541 { 542 this.titleBar.style.width = width + "px"; 543 } 544 } 545 else if (width === false) 546 { 547 this.width = null; 548 this.contentContainer.style.removeProperty("width"); 549 this.contentContainer.style.removeProperty("overflowX"); 550 if (this.titleBar) 551 { 552 this.titleBar.style.removeProperty("width"); 553 } 554 } 555}; 556 557/** 558 * 559 * @param {number} height 560 */ 561BX.PopupWindow.prototype.setHeight = function(height) 562{ 563 if (BX.type.isNumber(height) && height >= 0) 564 { 565 this.height = height; 566 this.contentContainer.style.height = height + "px"; 567 this.contentContainer.style.overflowY = "auto"; 568 } 569 else if (height === false) 570 { 571 this.height = null; 572 this.contentContainer.style.removeProperty("height"); 573 this.contentContainer.style.removeProperty("overflowY"); 574 } 575}; 576 577/** 578 * 579 * @param {object} options 580 * @param {number} [options.minWidth = 0] 581 * @param {number} [options.minHeight = 0] 582 * @param {bool} [options.restrict = true] 583 * 584 */ 585BX.PopupWindow.prototype.setResizeMode = function(options) 586{ 587 if (options === true || BX.type.isPlainObject(options)) 588 { 589 if (!this.resizeIcon) 590 { 591 this.resizeIcon = BX.create("div", { 592 props: { 593 className: "popup-window-resize" 594 }, 595 events: { 596 mousedown: BX.proxy(this.onResizeMouseDown, this) 597 } 598 }); 599 600 this.popupContainer.appendChild(this.resizeIcon); 601 } 602 603 if (BX.type.isNumber(options.minWidth) && options.minWidth > 0) 604 { 605 this.minWidth = options.minWidth; 606 } 607 608 if (BX.type.isNumber(options.minHeight) && options.minHeight > 0) 609 { 610 this.minHeight = options.minHeight; 611 } 612 } 613 else if (options === false && this.resizeIcon) 614 { 615 BX.remove(this.resizeIcon); 616 this.resizeIcon = null; 617 } 618}; 619 620/** 621 * 622 * @returns {number|null} 623 */ 624BX.PopupWindow.prototype.getWidth = function() 625{ 626 return this.width; 627}; 628 629/** 630 * 631 * @returns {number|null} 632 */ 633BX.PopupWindow.prototype.getHeight = function() 634{ 635 return this.height; 636}; 637 638BX.PopupWindow.prototype.onTitleMouseDown = function(event) 639{ 640 this._startDrag( 641 event, 642 { 643 cursor: "move", 644 callback: BX.proxy(this.move, this), 645 eventName: "Drag" 646 } 647 ); 648}; 649 650BX.PopupWindow.prototype.onResizeMouseDown = function(event) 651{ 652 this._startDrag( 653 event, 654 { 655 cursor: "nwse-resize", 656 eventName: "Resize", 657 callback: BX.proxy(this._resize, this) 658 } 659 ); 660 661 this.resizeContentPos = BX.pos(this.contentContainer); 662 this.resizeContentOffset = this.resizeContentPos.left - BX.pos(this.popupContainer).left; 663}; 664 665BX.PopupWindow.prototype._resize = function(offsetX, offsetY, pageX, pageY) 666{ 667 var width = pageX - this.resizeContentPos.left; 668 var height = pageY - this.resizeContentPos.top; 669 670 var scrollWidth = BX.GetWindowScrollSize().scrollWidth; 671 if (this.resizeContentPos.left + width + this.resizeContentOffset >= scrollWidth) 672 { 673 width = scrollWidth - this.resizeContentPos.left - this.resizeContentOffset; 674 } 675 676 this.setWidth(Math.max(width, this.minWidth)); 677 this.setHeight(Math.max(height, this.minHeight)); 678}; 679 680BX.PopupWindow.prototype.isTopAngle = function() 681{ 682 return this.angle !== null && this.angle.position === "top"; 683}; 684 685BX.PopupWindow.prototype.isBottomAngle = function() 686{ 687 return this.angle !== null && this.angle.position === "bottom"; 688}; 689 690BX.PopupWindow.prototype.isTopOrBottomAngle = function() 691{ 692 return this.angle !== null && BX.util.in_array(this.angle.position, ["to
692p", "bottom"]); 693}; 694 695BX.PopupWindow.prototype.getAngleHeight = function() 696{ 697 return (this.isTopOrBottomAngle() ? BX.PopupWindow.getOption("angleTopOffset") : 0); 698}; 699 700/** 701 * 702 * @param {object} params 703 * @param {number} [params.offsetLeft] 704 * @param {number} [params.offsetTop] 705 */ 706BX.PopupWindow.prototype.setOffset = function(params) 707{ 708 if (!BX.type.isPlainObject(params)) 709 { 710 return; 711 } 712 713 if (params.offsetLeft && BX.type.isNumber(params.offsetLeft)) 714 { 715 this.offsetLeft = params.offsetLeft + BX.PopupWindow.getOption("offsetLeft"); 716 } 717 718 if (params.offsetTop && BX.type.isNumber(params.offsetTop)) 719 { 720 this.offsetTop = params.offsetTop + BX.PopupWindow.getOption("offsetTop"); 721 } 722}; 723 724/** 725 * 726 * @param {object|string} params 727 * @param {Element} [params.content] 728 */ 729BX.PopupWindow.prototype.setTitleBar = function(params) 730{ 731 if (!this.titleBar) 732 { 733 return; 734 } 735 736 if (typeof(params) === "object" && BX.type.isDomNode(params.content)) 737 { 738 this.titleBar.innerHTML = ""; 739 this.titleBar.appendChild(params.content); 740 } 741 else if (typeof(params) === "string") 742 { 743 this.titleBar.innerHTML = ""; 744 this.titleBar.appendChild( 745 BX.create("span", { 746 props : { 747 className: "popup-window-titlebar-text" 748 }, 749 text : params 750 }) 751 ); 752 } 753 754 if (this.params.draggable) 755 { 756 this.titleBar.style.cursor = "move"; 757 BX.bind(this.titleBar, "mousedown", BX.proxy(this.onTitleMouseDown, this)); 758 } 759}; 760 761/** 762 * 763 * @param {bool} enable 764 */ 765BX.PopupWindow.prototype.setClosingByEsc = function(enable) 766{ 767 enable = BX.type.isBoolean(enable) ? enable : true; 768 if (enable) 769 { 770 this.closeByEsc = true; 771 if (!this.isCloseByEscBinded) 772 { 773 BX.bind(document, "keyup", BX.proxy(this._onKeyUp, this)); 774 this.isCloseByEscBinded = true; 775 } 776 } 777 else 778 { 779 this.closeByEsc = false; 780 if (this.isCloseByEscBinded) 781 { 782 BX.unbind(document, "keyup", BX.proxy(this._onKeyUp, this)); 783 this.isCloseByEscBinded = false; 784 } 785 } 786}; 787 788/** 789 * 790 * @param {bool} enable 791 */ 792BX.PopupWindow.prototype.setAutoHide = function(enable) 793{ 794 enable = BX.type.isBoolean(enable) ? enable : true; 795 if (enable) 796 { 797 this.autoHide = true; 798 if (this.isShown()) 799 { 800 this.bindAutoHide(); 801 } 802 } 803 else 804 { 805 this.autoHide = false;
806 this.unbindAutoHide(); 807 } 808}; 809 810BX.PopupWindow.prototype.bindAutoHide = function() 811{ 812 if (!this.isAutoHideBinded) 813 { 814 this.isAutoHideBinded = true; 815 BX.bind(this.popupContainer, "click", this.cancelBubble); 816 if(this.overlay && this.overlay.element) 817 BX.bind(this.overlay.element, "click", BX.proxy(this.close, this)); 818 else 819 BX.bind(document, "click", BX.proxy(this.close, this)); 820 } 821}; 822 823BX.PopupWindow.prototype.unbindAutoHide = function() 824{ 825 if (this.isAutoHideBinded) 826 { 827 this.isAutoHideBinded = false; 828 BX.unbind(this.popupContainer, "click", this.cancelBubble); 829 if(this.overlay && this.overlay.element) 830 BX.unbind(this.overlay.element, "click", BX.proxy(this.close, this)); 831 else 832 BX.unbind(document, "click", BX.proxy(this.close, this)); 833 } 834}; 835 836/** 837 * 838 * @param {object} params 839 * @param {number} [params.opacity] 840 * @param {string} [params.backgroundColor] 841 */ 842BX.PopupWindow.prototype.setOverlay = function(params) 843{ 844 if (this.overlay === null) 845 { 846 this.overlay = { 847 element : BX.create("div", { 848 props : { 849 className: "popup-window-overlay", id : "popup-window-overlay-" + this.uniquePopupId 850 } 851 }) 852 }; 853 854 this.adjustOverlayZindex(); 855 this.resizeOverlay(); 856 857 this.appendContainer.appendChild(this.overlay.element); 858 } 859 860 if (params && params.hasOwnProperty('opacity') && BX.type.isNumber(params.opacity) && params.opacity >= 0 && params.opacity <= 100) 861 { 862 if (BX.browser.IsIE() && !BX.browser.IsIE9()) 863 { 864 this.overlay.element.style.filter = "alpha(opacity=" + params.opacity +")"; 865 } 866 else 867 { 868 this.overlay.element.style.filter = "none"; 869 this.overlay.element.style.opacity = parseFloat(params.opacity/100).toPrecision(3); 870 } 871 } 872 873 if (params && params.backgroundColor) 874 { 875 this.overlay.element.style.backgroundColor = params.backgroundColor; 876 } 877}; 878 879BX.PopupWindow.prototype.removeOverlay = function() 880{ 881 if (this.overlay !== null && this.overlay.element !== null) 882 { 883 BX.remove(this.overlay.element); 884 } 885 886 if (this.overlayTimeout) 887 { 888 clearInterval(this.overlayTimeout); 889 this.overlayTimeout = null; 890 } 891 892 this.overlay = null; 893}; 894 895BX.PopupWindow.prototype.hideOverlay = function() 896{ 897 if (this.overlay !== null && this.overlay.element !== null) 898 { 899 if (this.overlayTimeout) 900 { 901 clearInterval(this.overlayTimeout); 902 this.overlayTimeout = null; 903 } 904 905 this.overlay.element.style.display = "none"; 906 } 907}; 908 909BX.PopupWindow.prototype.showOverlay = function() 910{ 911 if (this.overlay !== null && this.overlay.element !== null) 912 { 913 this.overlay.element.style.display = "block"; 914 915 var popupHeight = this.popupContainer.offsetHeight; 916 this.overlayTimeout = setInterval(function() { 917 if (popupHeight !== this.popupContainer.offsetHeight) 918 { 919 this.resizeOverlay(); 920 popupHeight = this.popupContainer.offsetHeight; 921 } 922 923 }.bind(this), 1000); 924 } 925}; 926 927BX.PopupWindow.prototype.resizeOverlay = function() 928{ 929 if (this.overlay !== null && this.overlay.element !== null) 930 { 931 if (this.parentPopup) 932 { 933 this.overlay.element.style.width = this.parentPopup.popupContainer.offsetWidth + "px"; 934 this.overlay.element.style.height = this.parentPopup.popupContainer.offsetHeight + "px"; 935 } 936 else 937 { 938 var windowSize = BX.GetWindowScrollSize(); 939 var scrollHeight = Math.max( 940 document.body.scrollHeight, document.documentElement.scrollHeight, 941 document.body.offsetHeight, document.documentElement.offsetHeight, 942 document.body.clientHeight, document.documentElement.clientHeight 943 ); 944 945 this.overlay.element.style.width = windowSize.scrollWidth + "px"; 946 this.overlay.element.style.height = scrollHeight + "px"; 947 } 948 } 949}; 950 951BX.PopupWindow.prototype.getZindex = function() 952{ 953 if (this.overlay !== null) 954 { 955 return BX.PopupWindow.getOption("popupOverlayZindex") + this.params.zIndex; 956 } 957 else 958 { 959 return BX.PopupWindow.getOption("popupZindex") + this.params.zIndex; 960 } 961}; 962 963BX.PopupWindow.prototype.adjustOverlayZindex = function() 964{ 965 if (this.overlay !== null && this.overlay.element !== null) 966 { 967 this.overlay.element.style.zIndex = parseInt(this.popupContainer.style.zIndex) - 1; 968 } 969}; 970 971BX.PopupWindow.prototype.show = function() 972{ 973 if (!this.firstShow) 974 { 975 BX.onCustomEvent(this, "onPopupFirstShow", [this]); 976 this.firstShow = true; 977 } 978 BX.onCustomEvent(this, "onPopupShow", [this]); 979 980 this.showOverlay(); 981 this.popupContainer.style.display = "block"; 982 983 this.adjustPosition(); 984 985 BX.onCustomEvent(this, "onAfterPopupShow", [this]); 986 987 if (this.closeByEsc && !this.isCloseByEscBinded) 988 { 989 BX.bind(document, "keyup", BX.proxy(this._onKeyUp, this)); 990 this.isCloseByEscBinded = true; 991 } 992 993 if (this.autoHide && !this.isAutoHideBinded) 994 { 995 setTimeout( 996 BX.proxy(function() { 997 if (this.isShown()) 998 { 999 this.bindAutoHide(); 1000 } 1001 }, this), 100 1002 ); 1003 } 1004}; 1005 1006BX.PopupWindow.prototype.isShown = function() 1007{ 1008 return this.popupContainer.style.display === "block"; 1009}; 1010 1011BX.PopupWindow.prototype.cancelBubble = function(event) 1012{ 1013 event = event || window.event; 1014 1015 if (event.stopPropagation) 1016 { 1017 event.stopPropagation(); 1018 } 1019 else 1020 { 1021 event.cancelBubble = true; 1022 } 1023}; 1024 1025BX.PopupWindow.prototype.close = function(event) 1026{ 1027 if (!this.isShown()) 1028 { 1029 return; 1030 } 1031 1032 if (event && !(BX.getEventButton(event) & BX.MSLEFT)) 1033 { 1034 return true; 1035 } 1036 1037 BX.onCustomEvent(this, "onPopupClose", [this, event]); 1038 1039 this.hideOverlay(); 1040 this.popupContainer.style.display = "none"; 1041 1042 if (this.isCloseByEscBinded) 1043 { 1044 BX.unbind(document, "keyup", BX.proxy(this._onKeyUp, this)); 1045 this.isCloseByEscBinded = false;
1046 } 1047 1048 setTimeout(BX.proxy(this._close, this), 0); 1049}; 1050 1051BX.PopupWindow.prototype._close = function() 1052{ 1053 if (this.autoHide) 1054 { 1055 this.unbindAutoHide(); 1056 } 1057}; 1058 1059BX.PopupWindow.prototype._onCloseIconClick = function(event) 1060{ 1061 event = event || window.event; 1062 this.close(event); 1063 BX.PreventDefault(event); 1064}; 1065 1066BX.PopupWindow.prototype._onKeyUp = function(event) 1067{ 1068 event = event || window.event; 1069 if (event.keyCode === 27) 1070 { 1071 _checkEscPressed(this.getZindex(), BX.proxy(this.close, this)); 1072 } 1073}; 1074 1075BX.PopupWindow.prototype.destroy = function() 1076{ 1077 BX.onCustomEvent(this, "onPopupDestroy", [this]); 1078 BX.unbindAll(this); 1079 BX.unbind(document, "keyup", BX.proxy(this._onKeyUp, this)); 1080 BX.unbind(document, "click", BX.proxy(this.close, this)); 1081 BX.unbind(document, "mousemove", BX.proxy(this._moveDrag, this)); 1082 BX.unbind(document, "mouseup", BX.proxy(this._stopDrag, this)); 1083 BX.unbind(window, "resize", BX.proxy(this._onResizeWindow, this)); 1084 BX.remove(this.popupContainer); 1085 this.removeOverlay(); 1086}; 1087 1088BX.PopupWindow.prototype.enterFullScreen = function() 1089{ 1090 if (BX.PopupWindow.fullscreenStatus) 1091 { 1092 if (document.cancelFullScreen) 1093 { 1094 document.cancelFullScreen(); 1095 } 1096 else if (document.mozCancelFullScreen) 1097 { 1098 document.mozCancelFullScreen(); 1099 } 1100 else if (document.webkitCancelFullScreen) 1101 { 1102 document.webkitCancelFullScreen(); 1103 } 1104 } 1105 else 1106 { 1107 if (BX.browser.IsChrome() || BX.browser.IsSafari()) 1108 { 1109 this.contentContainer.webkitRequestFullScreen(this.contentContainer.ALLOW_KEYBOARD_INPUT); 1110 BX.bind(window, "webkitfullscreenchange", this.fullscreenBind = BX.proxy(this.eventFullScreen, this)); 1111 } 1112 else if (BX.browser.IsFirefox()) 1113 { 1114 this.contentContainer.mozRequestFullScreen(this.contentContainer.ALLOW_KEYBOARD_INPUT); 1115 BX.bind(window, "mozfullscreenchange", this.fullscreenBind = BX.proxy(this.eventFullScreen, this)); 1116 } 1117 } 1118}; 1119 1120BX.PopupWindow.prototype.eventFullScreen = function(event) 1121{ 1122 if (BX.PopupWindow.fullscreenStatus) 1123 { 1124 if (BX.browser.IsChrome() || BX.browser.IsSafari()) 1125 { 1126 BX.unbind(window, "webkitfullscreenchange", this.fullscreenBind); 1127 } 1128 else if (BX.browser.IsFirefox()) 1129 { 1130 BX.unbind(window, "mozfullscreenchange", this.fullscreenBind); 1131 } 1132 1133 BX.removeClass(this.contentContainer, "popup-window-fullscreen", [this.contentContainer]); 1134 1135 BX.PopupWindow.fullscreenStatus = false; 1136 BX.onCustomEvent(this, "onPopupFullscreenLeave"); 1137 this.adjustPosition(); 1138 } 1139 else 1140 { 1141 BX.addClass(this.contentContainer, "popup-window-fullscreen"); 1142 BX.PopupWindow.fullscreenStatus = true; 1143 BX.onCustomEvent(this, "onPopupFullscreenEnter", [this.contentContainer]); 1144 this.adjustPosition(); 1145 } 1146}; 1147 1148/** 1149 * 1150 * @param {object} bindOptions 1151 * @param {bool} [bindOptions.forceBindPosition] 1152 * @param {bool} [bindOptions.forceLeft] 1153 * @param {bool} [bindOptions.forceTop] 1154 * @param {string} [bindOptions.position = "bottom"] 1155 */ 1156BX.PopupWindow.prototype.adjustPosition = function(bindOptions) 1157{ 1158 if (bindOptions && typeof(bindOptions) === "object") 1159 { 1160 this.bindOptions = bindOptions; 1161 } 1162 1163 var bindElementPos = this.getBindElementPos(this.bindElement); 1164 1165 if ( 1166 !this.bindOptions.forceBindPosition && 1167 this.bindElementPos !== null && 1168 bindElementPos.top === this.bindElementPos.top && 1169 bindElementPos.left === this.bindElementPos.left 1170 ) 1171 { 1172 return; 1173 } 1174 1175 this.bindElementPos = bindElementPos; 1176 1177 var windowSize = bindElementPos.windowSize ? bindElementPos.windowSize : BX.GetWindowInnerSize(); 1178 var windowScroll = bindElementPos.windowScroll ? bindElementPos.windowScroll : BX.GetWindowScrollPos(); 1179 var popupWidth = bindElementPos.popupWidth ? bindElementPos.popupWidth : this.popupContainer.offsetWidth; 1180 var popupHeight = bindElementPos.popupHeight ? bindElementPos.popupHeight : this.popupContainer.offsetHeight; 1181 1182 var angleTopOffset = BX.PopupWindow.getOption("angleTopOffset"); 1183 1184 var left = this.bindElementPos.left + this.offsetLeft - 1185 (this.isTopOrBottomAngle() ? BX.PopupWindow.getOption("angleLeftOffset") : 0); 1186 1187 if ( 1188 !this.bindOptions.forceLeft && 1189 (left + popupWidth + this.bordersWidth) >= (windowSize.innerWidth + windowScroll.scrollLeft) && 1190 (windowSize.innerWidth + windowScroll.scrollLeft - popupWidth - this.bordersWidth) > 0) 1191 { 1192 var bindLeft = left; 1193 left = windowSize.innerWidth + windowScroll.scrollLeft - popupWidth - this.bordersWidth; 1194 if (this.isTopOrBottomAngle()) 1195 { 1196 this.setAngle({ offset : bindLeft - left + this.angle.defaultOffset}); 1197 } 1198 } 1199 else if (this.isTopOrBottomAngle()) 1200 { 1201 this.setAngle({ offset : this.angle.defaultOffset + (left < 0 ? left : 0) }); 1202 } 1203 1204 if (left < 0) 1205 { 1206 left = 0; 1207 } 1208 1209 var top = 0; 1210 1211 if (this.bindOptions.position && this.bindOptions.position === "top") 1212 { 1213 1214 top = this.bindElementPos.top - popupHeight - this.offsetTop - (this.isBottomAngle() ? angleTopOffset : 0); 1215 if (top < 0 || (!this.bindOptions.forceTop && top < windowScroll.scrollTop)) 1216 { 1217 top = this.bindElementPos.bottom + this.offsetTop; 1218 if (this.angle !== null) 1219 { 1220 top += angleTopOffset; 1221 this.setAngle({ position: "top"}); 1222 } 1223 } 1224 else if (this.isTopAngle()) 1225 { 1226 top = top - angleTopOffset + BX.PopupWindow.getOption("positionTopXOffset"); 1227 this.setAngle({ position: "bottom"}); 1228 } 1229 else 1230 { 1231 top += BX.PopupWindow.getOption("positionTopXOffset"); 1232 } 1233 } 1234 else 1235 { 1236 1237 top = this.bindElementPos.bottom + this.offsetTop + this.getAngleHeight(); 1238 1239 if ( 1240 !this.bindOptions.forceTop && 1241 (top + popupHeight) >
1241 (windowSize.innerHeight + windowScroll.scrollTop) && 1242 (this.bindElementPos.top - popupHeight - this.getAngleHeight()) >= 0) //Can we place the PopupWindow above the bindElement? 1243 { 1244 //The PopupWindow doesn't place below the bindElement. We should place it above. 1245 top = this.bindElementPos.top - popupHeight; 1246 1247 if (this.isTopOrBottomAngle()) 1248 { 1249 top -= angleTopOffset; 1250 this.setAngle({ position: "bottom"}); 1251 } 1252 1253 top += BX.PopupWindow.getOption("positionTopXOffset"); 1254 1255 } 1256 else if (this.isBottomAngle()) 1257 { 1258 top += angleTopOffset; 1259 this.setAngle({ position: "top"}); 1260 } 1261 } 1262 1263 if (!this.parentPopup && top < 0) 1264 { 1265 top = 0; 1266 } 1267 1268 BX.adjust(this.popupContainer, { style: { 1269 top: top + "px", 1270 left: left + "px", 1271 zIndex: this.getZindex() 1272 }}); 1273 1274 this.adjustOverlayZindex(); 1275}; 1276 1277BX.PopupWindow.prototype._onResizeWindow = function(event) 1278{ 1279 if (this.isShown()) 1280 { 1281 this.adjustPosition(); 1282 if (this.overlay !== null) 1283 { 1284 this.resizeOverlay(); 1285 } 1286 } 1287}; 1288 1289BX.PopupWindow.prototype.move = function(offsetX, offsetY, pageX, pageY) 1290{ 1291 var left = parseInt(this.popupContainer.style.left) + offsetX; 1292 var top = parseInt(this.popupContainer.style.top) + offsetY; 1293 1294 if (typeof(this.params.draggable) === "object" && this.params.draggable.restrict) 1295 { 1296 //Left side 1297 if (!this.parentPopup && left < 0) 1298 { 1299 left = 0; 1300 } 1301 1302 //Right side 1303 var scrollSize = BX.GetWindowScrollSize(); 1304 var floatWidth = this.popupContainer.offsetWidth; 1305 var floatHeight = this.popupContainer.offsetHeight; 1306 1307 if (left > (scrollSize.scrollWidth - floatWidth)) 1308 { 1309 left = scrollSize.scrollWidth - floatWidth; 1310 } 1311 1312 if (top > (scrollSize.scrollHeight - floatHeight)) 1313 { 1314 top = scrollSize.scrollHeight - floatHeight; 1315 } 1316 1317 //Top side 1318 if (!this.parentPopup && top < 0) 1319 { 1320 top = 0; 1321 } 1322 } 1323 1324 this.popupContainer.style.left = left + "px"; 1325 this.popupContainer.style.top = top + "px"; 1326}; 1327 1328BX.PopupWindow.prototype._startDrag = function(event, options) 1329{ 1330 event = event || window.event; 1331 BX.fixEventPageXY(event); 1332 1333 options = options || {}; 1334 if (BX.type.isNotEmptyString(options.cursor)) 1335 { 1336 this.dragOptions.cursor = options.cursor; 1337 } 1338 1339 if (BX.type.isNotEmptyString(options.eventName)) 1340 { 1341 this.dragOptions.eventName = options.eventName; 1342 } 1343 1344 if (BX.type.isFunction(options.callback)) 1345 { 1346 this.dragOptions.callback = options.callback; 1347 } 1348 1349 this.dragPageX = event.pageX; 1350 this.dragPageY = event.pageY; 1351 this.dragged = false; 1352 1353 BX.bind(document, "mousemove", BX.proxy(this._moveDrag, this)); 1354 BX.bind(document, "mouseup", BX.proxy(this._stopDrag, this)); 1355 1356 if (document.body.setCapture) 1357 { 1358 document.body.setCapture(); 1359 } 1360 1361 document.body.ondrag = BX.False; 1362 document.body.onselectstart = BX.False; 1363 document.body.style.cursor = this.dragOptions.cursor; 1364 document.body.style.MozUserSelect = "none"; 1365 this.popupContainer.style.MozUserSelect = "none"; 1366 1367 return BX.PreventDefault(event); 1368}; 1369 1370BX.PopupWindow.prototype._moveDrag = function(event) 1371{ 1372 event = event || window.event; 1373 BX.fixEventPageXY(event); 1374 1375 if (this.dragPageX === event.pageX && this.dragPageY === event.pageY) 1376 { 1377 return; 1378 } 1379 1380 this.dragOptions.callback( 1381 event.pageX - this.dragPageX, 1382 event.pageY - this.dragPageY, 1383 event.pageX, 1384 event.pageY 1385 ); 1386 1387 this.dragPageX = event.pageX; 1388 this.dragPageY = event.pageY; 1389 1390 if (!this.dragged) 1391 { 1392 BX.onCustomEvent(this, "onPopup" + this.dragOptions.eventName + "Start", [this]); 1393 this.dragged = true; 1394 } 1395 1396 BX.onCustomEvent(this, "onPopup" + this.dragOptions.eventName, [this]); 1397}; 1398 1399BX.PopupWindow.prototype._stopDrag = function(event) 1400{ 1401 if(document.body.releaseCapture) 1402 { 1403 document.body.releaseCapture(); 1404 } 1405 1406 BX.unbind(document, "mousemove", BX.proxy(this._moveDrag, this)); 1407 BX.unbind(document, "mouseup", BX.proxy(this._stopDrag, this)); 1408 1409 //document.onmousedown = null; 1410 document.body.ondrag = null; 1411 document.body.onselectstart = null; 1412 document.body.style.cursor = ""; 1413 document.body.style.MozUserSelect = ""; 1414 this.popupContainer.style.MozUserSelect = ""; 1415 1416 BX.onCustomEvent(this, "onPopup" + this.dragOptions.eventName + "End", [this]); 1417 this.dragged = false; 1418 1419 return BX.PreventDefault(event); 1420}; 1421 1422BX.PopupWindow.options = {}; 1423BX.PopupWindow.defaultOptions = { 1424 1425 angleLeftOffset : 40, /*left offset for popup about target */ 1426 1427 positionTopXOffset : -11, /* when popup position is 'top' offset distance between popup body and target node */ 1428 1429 angleTopOffset : 10, /* offset distance between popup body and target node if use angle, sum with positionTopXOffset */ 1430 1431 popupZindex : 1000, 1432 popupOverlayZindex : 1100, 1433 1434 angleMinLeft : 10, 1435 angleMaxLeft : 10, 1436 1437 angleMinRight : 10, 1438 angleMaxRight : 10, 1439 1440 angleMinBottom : 23, /**/ 1441 angleMaxBottom : 25, 1442 1443 angleMinTop : 23, 1444 angleMaxTop : 25, 1445 1446 offsetLeft : 0, 1447 offsetTop: 0 1448}; 1449 1450BX.PopupWindow.setOptions = function(options) 1451{ 1452 if (!options || typeof(options) !== "object") 1453 { 1454 return; 1455 } 1456 1457 for (var option in options) 1458 { 1459 BX.PopupWindow.options[option] = options[option]; 1460 } 1461}; 1462 1463BX.PopupWindow.getOption = function(option, defaultValue) 1464{ 1465 if (typeof(BX.PopupWindow.options[option]) !== "undefined") 1466 { 1467 return BX.PopupWindow.options[option]; 1468 } 1469 else if (typeof(defaultValue) !== "undefined") 1470 { 1471 return defaultValue; 1472 } 1473 else 1474 { 1475 return BX.PopupWindow.defaultOptions[option]; 1476 } 1477}; 1478 1479/** 1480 * 1481 * @param {object} params 1482 * @param {string} [params.text] 1483 * @param {string} [params.id] 1484 * @param {string} [params.className] 1485 * @param {object} [params.events] 1486 * @constructor 1487 */ 1488BX.PopupWindowButton = function(params) 1489{ 1490 this.popupWindow = null; 1491 1492 this.params = params || {}; 1493 1494 this.text = this.params.text || ""; 1495 this.id = this.params.id || ""; 1496 this.className = this.params.className || ""; 1497 this.events = this.params.events || {}; 1498 1499 this.contextEvents = {}; 1500 for (var eventName in this.events) 1501 { 1502 this.contextEvents[eventName] = BX.proxy(this.events[eventName], this); 1503 } 1504 1505 this.buttonNode = BX.create( 1506 "span", 1507 { 1508 props : { className : "popup-window-button" + (this.className.length > 0 ? " " + this.className : ""), id : this.id }, 1509 events : this.contextEvents, 1510 text : this.text 1511 } 1512 ); 1513}; 1514 1515BX.PopupWindowButton.prototype.render = function() 1516{ 1517 return this.buttonNode; 1518}; 1519 1520BX.PopupWindowButton.prototype.getId = function() 1521{ 1522 return this.id; 1523}; 1524 1525BX.PopupWindowButton.prototype.getName = function() 1526{ 1527 return this.name; 1528}; 1529 1530/** 1531 * 1532 * @returns {Element} 1533 */ 1534BX.PopupWindowButton.prototype.getContainer = function() 1535{ 1536 return this.buttonNode; 1537}; 1538 1539BX.PopupWindowButton.prototype.setName = function(name) 1540{ 1541 this.text = name || ""; 1542 if (this.buttonNode) 1543 { 1544 BX.cleanNode(this.buttonNode); 1545 BX.adjust(this.buttonNode, { text : this.text} ); 1546 } 1547}; 1548 1549BX.PopupWindowButton.prototype.setClassName = function(className) 1550{ 1551 if (this.buttonNode) 1552 { 1553 if (BX.type.isString(this.className) && (this.className !== "")) 1554 { 1555 BX.removeClass(this.buttonNode, this.className); 1556 } 1557 1558 BX.addClass(this.buttonNode, className) 1559 } 1560 1561 this.className = className; 1562}; 1563 1564BX.PopupWindowButton.prototype.addClassName = function(className) 1565{ 1566 if (this.buttonNode) 1567 { 1568 BX.addClass(this.buttonNode, className); 1569 this.className = this.buttonNode.className; 1570 } 1571}; 1572 1573BX.PopupWindowButton.prototype.removeClassName = function(className) 1574{ 1575 if (this.buttonNode) 1576 { 1577 BX.removeClass(this.buttonNode, className); 1578 this.className = this.buttonNode.className; 1579 } 1580}; 1581 1582BX.PopupWindowButtonLink = function(params) 1583{ 1584 BX.PopupWindowButtonLink.superclass.constructor.apply(this, arguments); 1585 1586 this.buttonNode = BX.create( 1587 "span", 1588 { 1589 props : { className : "popup-window-button popup-window-button-link" + (this.className.length > 0 ? " " + this.className : ""), id : this.id }, 1590 text : this.text, 1591 events : this.contextEvents 1592 } 1593 ); 1594 1595}; 1596 1597BX.extend(BX.PopupWindowButtonLink, BX.PopupWindowButton); 1598 1599BX.PopupWindowCustomButton = function(params) 1600{ 1601 BX.PopupWindowCustomButton.superclass.constructor.apply(this, arguments); 1602 1603 this.buttonNode = BX.create( 1604 "span", 1605 { 1606 props : { className : (this.className.length > 0 ? " " + this.className : ""), id : this.id }, 1607 events : this.contextEvents, 1608 text : this.text 1609 } 1610 ); 1611}; 1612 1613BX.extend(BX.PopupWindowCustomButton, BX.PopupWindowButton); 1614 1615BX.PopupMenu = { 1616 1617 Data : {}, 1618 currentItem : null, 1619 1620 show : function(id, bindElement, menuItems, params) 1621 { 1622 if (this.currentItem !== null) 1623 { 1624 this.currentItem.popupWindow.close(); 1625 } 1626 1627 this.currentItem = this.create(id, bindElement, menuItems, params); 1628 this.currentItem.popupWindow.show(); 1629 }, 1630 1631 create : function(id, bindElement, menuItems, params) 1632 { 1633 if (!this.Data[id]) 1634 { 1635 this.Data[id] = new BX.PopupMenuWindow(id, bindElement, menuItems, params); 1636 BX.addCustomEvent(this.Data[id], 'onPopupMenuDestroy', this.onPopupDestroy.bind(this)); 1637 } 1638 return this.Data[id]; 1639 }, 1640 1641 getCurrentMenu : function() 1642 { 1643 return this.currentItem; 1644 }, 1645 1646 getMenuById : function(id) 1647 { 1648 return this.Data[id] ? this.Data[id] : null; 1649 }, 1650 1651 onPopupDestroy: function(popupMenuWindow) 1652 { 1653 this.destroy(popupMenuWindow.id); 1654 }, 1655 1656 destroy : function(id) 1657 { 1658 var menu = this.getMenuById(id); 1659 if (menu) 1660 { 1661 if (this.currentItem === menu) 1662 { 1663 this.currentItem = null; 1664 } 1665 menu.popupWindow.destroy(); 1666 delete this.Data[id]; 1667 } 1668 } 1669}; 1670 1671BX.PopupMenuWindow = function(id, bindElement, menuItems, params) 1672{ 1673 this.id = id; 1674 this.bindElement = bindElement; 1675 1676 /** 1677 * 1678 * @type {BX.PopupMenuItem[]} 1679 */ 1680 this.menuItems = []; 1681 this.itemsContainer = null; 1682 this.params = params && typeof(params) === "object" ? params : {}; 1683 this.parentMenuWindow = null; 1684 this.parentMenuItem = null; 1685 1686 if (menuItems && BX.type.isArray(menuItems)) 1687 { 1688 for (var i = 0; i < menuItems.length; i++) 1689 { 1690 this.addMenuItemInternal(menuItems[i], null); 1691 } 1692 } 1693 1694 this.layout = { 1695 menuContainer: null, 1696 itemsContainer: null 1697 }; 1698 1699 this.popupWindow = this.__createPopup(); 1700}; 1701 1702BX.PopupMenuWindow.prototype.__createPopup = function() 1703{ 1704 var domItems = []; 1705 for (var i = 0; i < this.menuItems.length; i++) 1706 { 1707 var item = this.menuItems[i]; 1708 var itemLayout = item.getLayout(); 1709 domItems.push(itemLayout.item); 1710 } 1711 1712 var popupWindow = new BX.PopupWindow("menu-popup-" + this.id, this.bindElement, { 1713 closeByEsc: typeof(this.params.closeByEsc) !== "undefined" ? this.params.closeByEsc: false, 1714 bindOptions: typeof(this.params.bindOptions) === "object" ? this.params.bindOptions : {}, 1715 angle: typeof(this.params.angle) !== "undefined" ? this.params.angle : false, 1716 zIndex: this.params.zIndex ? this.params.zIndex : 0, 1717 overlay: typeof(this.params.overlay) === "object" ? this.params.overlay : null, 1718 autoHide: typeof(this.params.autoHide) !== "undefined" ? this.params.autoHide : true, 1719 offsetTop: this.params.offsetTop ? this.params.offsetTop : 1, 1720 offsetLeft: this.params.offsetLeft ? this.params.offsetLeft : 0, 1721 className: BX.type.isNotEmptyString(this.params.className) ? this.params.className : "", 1722 noAllPaddings: true, 1723 content : (this.layout.menuContainer = BX.create("div", { 1724 props : { 1725 className : "menu-popup" 1726 }, 1727 children: [ 1728 (this.layout.itemsContainer = this.itemsContainer = BX.create("div", { 1729 props : { 1730 className : "menu-popup-items" 1731 }, 1732 children: domItems 1733 })) 1734 ] 1735 })), 1736 events: { 1737 onPopupClose: this.onMenuWindowClose.bind(this), 1738 onPopupDestroy: this.onMenuWindowDestroy.bind(this) 1739 } 1740 }); 1741 1742 if (this.params && this.params.events) 1743 { 1744 for (var eventName in this.params.events) 1745 { 1746 if (this.params.events.hasOwnProperty(eventName)) 1747 { 1748 BX.addCustomEvent(popupWindow, eventName, this.params.events[eventName]); 1749 } 1750 } 1751 } 1752 1753 return popupWindow; 1754}; 1755 1756/** 1757 * 1758 * @returns {BX.PopupWindow} 1759 */ 1760BX.PopupMenuWindow.prototype.getPopupWindow = function() 1761{ 1762 return this.popupWindow; 1763}; 1764 1765BX.PopupMenuWindow.prototype.show = function() 1766{ 1767 this.popupWindow.show(); 1768}; 1769 1770BX.PopupMenuWindow.prototype.close = function() 1771{ 1772 this.popupWindow.close(); 1773}; 1774 1775BX.PopupMenuWindow.prototype.destroy = function() 1776{ 1777 BX.onCustomEvent(this, "onPopupMenuDestroy", [this]); 1778 this.popupWindow.destroy(); 1779}; 1780 1781BX.PopupMenuWindow.prototype.onMenuWindowClose = function() 1782{ 1783 for (var i = 0; i < this.menuItems.length; i++) 1784 { 1785 var item = this.menuItems[i]; 1786 item.closeSubMenu(); 1787 } 1788}; 1789 1790BX.PopupMenuWindow.prototype.onMenuWindowDestroy = function() 1791{ 1792 for (var i = 0; i < this.menuItems.length; i++) 1793 { 1794 var item = this.menuItems[i]; 1795 item.destroySubMenu(); 1796 } 1797}; 1798 1799/** 1800 * 1801 * @param {BX.PopupMenuWindow} parentMenuWindow 1802 */ 1803BX.PopupMenuWindow.prototype.setParentMenuWindow = function(parentMenuWindow) 1804{ 1805 if (parentMenuWindow instanceof BX.PopupMenuWindow) 1806 { 1807 this.parentMenuWindow = parentMenuWindow; 1808 } 1809}; 1810 1811/** 1812 * 1813 * @returns {BX.PopupMenuWindow|null} 1814 */ 1815BX.PopupMenuWindow.prototype.getParentMenuWindow = function() 1816{ 1817 return this.parentMenuWindow; 1818}; 1819 1820/** 1821 * 1822 * @param {BX.PopupMenuItem} parentMenuItem 1823 */ 1824BX.PopupMenuWindow.prototype.setParentMenuItem = function(parentMenuItem) 1825{ 1826 if (parentMenuItem instanceof BX.PopupMenuItem) 1827 { 1828 this.parentMenuItem = parentMenuItem; 1829 } 1830}; 1831 1832/** 1833 * 1834 * @returns {BX.PopupMenuItem} 1835 */ 1836BX.PopupMenuWindow.prototype.getParentMenuItem = function() 1837{ 1838 return this.parentMenuItem; 1839}; 1840 1841/** 1842 * 1843 * @param menuItemJson 1844 * @param targetItemId 1845 * @returns {BX.PopupMenuItem} 1846 */ 1847BX.PopupMenuWindow.prototype.addMenuItem = function(menuItemJson, targetItemId) 1848{ 1849 var menuItem = this.addMenuItemInternal(menuItemJson, targetItemId); 1850 if (!menuItem) 1851 { 1852 return null; 1853 } 1854 1855 var itemLayout = menuItem.getLayout(); 1856 var targetItem = this.getMenuItem(targetItemId); 1857 if (targetItem !== null) 1858 { 1859 var targetLayout = targetItem.getLayout(); 1860 this.itemsContainer.insertBefore(itemLayout.item, targetLayout.item); 1861 } 1862 else 1863 { 1864 this.itemsContainer.appendChild(itemLayout.item); 1865 } 1866 1867 return menuItem; 1868}; 1869 1870/** 1871 * 1872 * @param menuItemJson 1873 * @param targetItemId 1874 * @returns {BX.PopupMenuItem} 1875 */ 1876BX.PopupMenuWindow.prototype.addMenuItemInternal = function(menuItemJson, targetItemId) 1877{ 1878 if ( 1879 !menuItemJson ||
1880 (!menuItemJson.delimiter && !BX.type.isNotEmptyString(menuItemJson.text)) || 1881 (menuItemJson.id && this.getMenuItem(menuItemJson.id) !== null) 1882 ) 1883 { 1884 return null; 1885 } 1886 1887 if (BX.type.isNumber(this.params.menuShowDelay)) 1888 { 1889 menuItemJson.menuShowDelay = this.params.menuShowDelay; 1890 } 1891 1892 var menuItem = new BX.PopupMenuItem(menuItemJson); 1893 menuItem.setMenuWindow(this); 1894 1895 var position = this.getMenuItemPosition(targetItemId); 1896 if (position >= 0) 1897 { 1898 this.menuItems = BX.util.insertIntoArray(this.menuItems, position, menuItem); 1899 } 1900 else 1901 { 1902 this.menuItems.push(menuItem); 1903 } 1904 1905 return menuItem; 1906}; 1907 1908BX.PopupMenuWindow.prototype.removeMenuItem = function(itemId) 1909{ 1910 var item = this.getMenuItem(itemId); 1911 if (!item) 1912 { 1913 return; 1914 } 1915 1916 for (var position = 0; position < this.menuItems.length; position++) 1917 { 1918 if (this.menuItems[position] === item) 1919 { 1920 item.destroySubMenu(); 1921 this.menuItems = BX.util.deleteFromArray(this.menuItems, position); 1922 break; 1923 } 1924 } 1925 1926 if (!this.menuItems.length) 1927 { 1928 var menuWindow = item.getMenuWindow(); 1929 if (menuWindow) 1930 { 1931 var parentMenuItem = menuWindow.getParentMenuItem(); 1932 if (parentMenuItem) 1933 { 1934 parentMenuItem.destroySubMenu(); 1935 } 1936 else 1937 { 1938 menuWindow.destroy(); 1939 } 1940 } 1941 } 1942 1943 item.layout.item.parentNode.removeChild(item.layout.item); 1944 item.layout = { 1945 item: null, 1946 text: null 1947 }; 1948}; 1949 1950/** 1951 * 1952 * @param itemId 1953 * @returns {BX.PopupMenuItem} 1954 */ 1955BX.PopupMenuWindow.prototype.getMenuItem = function(itemId) 1956{ 1957 for (var i = 0; i < this.menuItems.length; i++) 1958 { 1959 if (this.menuItems[i].id && this.menuItems[i].id === itemId) 1960 { 1961 return this.menuItems[i]; 1962 } 1963 } 1964 1965 return null; 1966}; 1967 1968/** 1969 * 1970 * @returns {BX.PopupMenuItem[]} 1971 */ 1972BX.PopupMenuWindow.prototype.getMenuItems = function() 1973{ 1974 return this.menuItems; 1975}; 1976 1977/** 1978 * 1979 * @param itemId 1980 * @returns {number} 1981 */ 1982BX.PopupMenuWindow.prototype.getMenuItemPosition = function(itemId) 1983{ 1984 if (itemId) 1985 { 1986 for (var i = 0; i < this.menuItems.length; i++) 1987 { 1988 if (this.menuItems[i].id && this.menuItems[i].id === itemId) 1989 { 1990 return i; 1991 } 1992 } 1993 } 1994 1995 return -1; 1996}; 1997 1998/** 1999 * 2000 * @param {Object} options 2001 * @param {string} [options.id] 2002 * @param {string} [options.text] 2003 * @param {string} [options.title = ""] 2004 * @param {string} [options.href = null] 2005 * @param {string} [options.target = null] 2006 * @param {string} [options.className = null] 2007 * @param {boolean} [options.delimiter = false] 2008 * @param {number} [options.menuShowDelay = 300] 2009 * @param {number} [options.subMenuOffsetX = 4] 2010 * @param {object} [options.events] 2011 * @param {object} [options.dataset] 2012 * @param {function|string} [options.onclick = null] 2013 * @param {array[]} [options.items = []] 2014 * @constructor 2015 */ 2016BX.PopupMenuItem = function(options) 2017{ 2018 options = options || {}; 2019 this.options = options; 2020 2021 this.id = options.id || BX.util.getRandomString().toLowerCase(); 2022 this.text = BX.type.isNotEmptyString(options.text) ? options.text : ""; 2023 this.title = BX.type.isNotEmptyString(options.title) ? options.title : ""; 2024 this.delimiter = options.delimiter === true; 2025 this.href = BX.type.isNotEmptyString(options.href) ? options.href : null; 2026 this.target = BX.type.isNotEmptyString(options.target) ? options.target : null; 2027 this.dataset = BX.type.isPlainObject(options.dataset) ? options.dataset : null; 2028 this.className = BX.type.isNotEmptyString(options.className) ? options.className : null; 2029 this.menuShowDelay = BX.type.isNumber(options.menuShowDelay) ? options.menuShowDelay : 300; 2030 this.subMenuOffsetX = BX.type.isNumber(options.subMenuOffsetX) ? options.subMenuOffsetX : 4; 2031 this._items = BX.type.isArray(options.items) ? options.items : []; 2032 2033 /** 2034 * 2035 * @type {function|string} 2036 */ 2037 this.onclick = 2038 BX.type.isNotEmptyString(options.onclick) || BX.type.isFunction(options.onclick) 2039 ? options.onclick 2040 : null 2041 ; 2042 2043 if (BX.type.isPlainObject(options.events)) 2044 { 2045 for (var eventName in options.events) 2046 { 2047 BX.addCustomEvent(this, eventName, options.events[eventName]); 2048 } 2049 } 2050 2051 /** 2052 * 2053 * @type {BX.PopupMenuWindow} 2054 */ 2055 this.menuWindow = null; 2056 2057 /** 2058 * 2059 * @type {BX.PopupMenuWindow} 2060 */ 2061 this.subMenuWindow = null; 2062 2063 this.layout = { 2064 item: null, 2065 text: null 2066 }; 2067 2068 this.getLayout(); //compatibility 2069 2070 //compatibility 2071 //now use this.options 2072 this.events = {}; 2073 this.items = []; 2074 for (var property in options) 2075 { 2076 if (options.hasOwnProperty(property) && typeof(this[property]) === "undefined") 2077 { 2078 this[property] = options[property]; 2079 } 2080 } 2081}; 2082 2083BX.PopupMenuItem.prototype = { 2084 2085 getLayout: function() 2086 { 2087 if (this.layout.item) 2088 { 2089 return this.layout; 2090 } 2091 2092 if (this.delimiter) 2093 { 2094 this.layout.item = BX.create("span", { 2095 props: { 2096 className: "popup-window-delimiter" 2097 } 2098 }); 2099 } 2100 else 2101 { 2102 this.layout.item = BX.create(this.href ? "a" : "span", { 2103 props : { 2104 className: [ 2105 "menu-popup-item", 2106 (this.className ? this.className : "menu-popup-no-icon"), 2107 (this.hasSubMenu() ? "menu-popup-item-submenu" : "") 2108 ].join(" ") 2109 }, 2110 2111 attrs : { 2112 title : this.title, 2113 onclick: BX.type.isString(this.onclick) ? this.onclick : "", // compatibility 2114 target : this.target ? this.target : "" 2115 }, 2116 2117 dataset: this.dataset, 2118 2119 events : 2120 BX.type.isFunction(this.onclick) 2121 ? { click : BX.delegate(this.onItemClick, this) } 2122 : null 2123 , 2124 2125 children : [ 2126 BX.create("span", { props : { className: "menu-popup-item-icon"} }), 2127 (this.layout.text = BX.create("span", { 2128 props : { 2129 className: "menu-popup-item-text" 2130 }, 2131 html : this.text 2132 })) 2133 ] 2134 }); 2135 2136 if (this.href) 2137 { 2138 this.layout.item.href = this.href; 2139 } 2140 2141 BX.bind(this.layout.item, "mouseenter", this.onItemMouseEnter.bind(this)); 2142 BX.bind(this.layout.item, "mouseleave", this.onItemMouseLeave.bind(this)); 2143 } 2144 2145 return this.layout; 2146 }, 2147 2148 onItemClick: function(event) 2149 { 2150 this.onclick.call(this.menuWindow, event, this); //compatibility 2151 }, 2152 2153 onItemMouseEnter: function(event) 2154 { 2155 BX.onCustomEvent(this, "onMouseEnter"); 2156 2157 if (this.subMenuTimeout) 2158 { 2159 clearTimeout(this.subMenuTimeout); 2160 } 2161 2162 if (this.hasSubMenu()) 2163 { 2164 this.subMenuTimeout = setTimeout(function() { 2165 this.showSubMenu(); 2166 }.bind(this), this.menuShowDelay); 2167 } 2168 else 2169 { 2170 this.subMenuTimeout = setTimeout(function() { 2171 this.closeSiblings(); 2172 }.bind(this), this.menuShowDelay); 2173 } 2174 }, 2175 2176 onItemMouseLeave: function(event) 2177 { 2178 BX.onCustomEvent(this, "onMouseLeave"); 2179 2180 if (this.subMenuTimeout) 2181 { 2182 clearTimeout(this.subMenuTimeout); 2183 } 2184 }, 2185 2186 hasSubMenu: function() 2187 { 2188 return this.subMenuWindow !== null || this._items.length; 2189 }, 2190 2191 showSubMenu: function() 2192 { 2193 this.addSubMenu(this._items); 2194 2195 if (this.subMenuWindow) 2196 { 2197 BX.addClass(this.layout.item, "menu-popup-item-open"); 2198 2199 this.closeSiblings(); 2200 this.closeChildren(); 2201 2202 var popupWindow = this.subMenuWindow.getPopupWindow(); 2203 if (!popupWindow.isShown()) 2204 { 2205 BX.onCustomEvent(this, "onSubMenuShow"); 2206 popupWindow.show(); 2207 } 2208 2209 2210 this.adjustSubMenu(); 2211 } 2212 }, 2213 2214 addSubMenu: function(items) 2215 {
2216 if (this.subMenuWindow !== null || !BX.type.isArray(items) || !items.length) 2217 { 2218 return; 2219 } 2220 2221 this.subMenuWindow = new BX.PopupMenuWindow( 2222 "popup-submenu-" + this.id, 2223 null, 2224 items, 2225 { 2226 autoHide: false, 2227 menuShowDelay: this.menuShowDelay, 2228 bindOptions: { 2229 forceTop: true, 2230 forceLeft: true, 2231 forceBindPosition: true 2232 } 2233 } 2234 ); 2235 2236 this.subMenuWindow.setParentMenuWindow(this.menuWindow); 2237 this.subMenuWindow.setParentMenuItem(this); 2238 2239 BX.addClass(this.layout.item, "menu-popup-item-submenu"); 2240 }, 2241 2242 closeSubMenu: function() 2243 { 2244 if (this.subMenuWindow) 2245 { 2246 2247 BX.removeClass(this.layout.item, "menu-popup-item-open"); 2248 2249 this.closeChildren(); 2250 2251 var popupWindow = this.subMenuWindow.getPopupWindow(); 2252 if (popupWindow.isShown()) 2253 { 2254 BX.onCustomEvent(this, "onSubMenuClose"); 2255 popupWindow.close(); 2256 } 2257 2258 this.subMenuWindow.close(); 2259 } 2260 }, 2261 2262 closeSiblings: function() 2263 { 2264 var siblings = this.menuWindow.getMenuItems(); 2265 for (var i = 0; i < siblings.length; i++) 2266 { 2267 if (siblings[i] !== this) 2268 { 2269 siblings[i].closeSubMenu(); 2270 } 2271 } 2272 }, 2273 2274 closeChildren: function() 2275 { 2276 if (this.subMenuWindow) 2277 { 2278 var children = this.subMenuWindow.getMenuItems(); 2279 for (var i = 0; i < children.length; i++) 2280 { 2281 children[i].closeSubMenu(); 2282 } 2283 } 2284 }, 2285 2286 destroySubMenu: function() 2287 { 2288 if (this.subMenuWindow) 2289 { 2290 BX.removeClass(this.layout.item, "menu-popup-item-open menu-popup-item-submenu"); 2291 this.destroyChildren(); 2292 this.subMenuWindow.destroy(); 2293 2294 this.subMenuWindow = null; 2295 this._items = []; 2296 } 2297 }, 2298 2299 destroyChildren: function() 2300 { 2301 if (this.subMenuWindow) 2302 { 2303 var children = this.subMenuWindow.getMenuItems(); 2304 for (var i = 0; i < children.length; i++) 2305 { 2306 children[i].destroySubMenu(); 2307 } 2308 } 2309 }, 2310 2311 adjustSubMenu: function() 2312 { 2313 if (!this.subMenuWindow || !this.layout.item) 2314 { 2315 return; 2316 } 2317 2318 var popupWindow = this.subMenuWindow.getPopupWindow(); 2319 var itemRect = BX.pos(this.layout.item); 2320 2321 var offsetLeft = itemRect.width + this.subMenuOffsetX; 2322 var anglePosition = "left"; 2323 2324 var popupWidth = popupWindow.popupContainer.offsetWidth; 2325 var clientWidth = document.documentElement.clientWidth; 2326 if ((itemRect.left + offsetLeft + popupWidth) > clientWidth) 2327 { 2328 var left = itemRect.left - popupWidth - this.subMenuOffsetX; 2329 if (left > 0) 2330 { 2331 offsetLeft = -popupWidth - this.subMenuOffsetX; 2332 anglePosition = "right"; 2333 } 2334 } 2335 2336 popupWindow.setBindElement(this.layout.item); 2337 2338 popupWindow.setOffset({ 2339 offsetLeft: offsetLeft, 2340 offsetTop: -(itemRect.height + this.getPopupPadding()) 2341 }); 2342 2343 popupWindow.setAngle({ 2344 "position": anglePosition, 2345 "offset": ((itemRect.height / 2) - this.getPopupPadding()) 2346 }); 2347 2348 popupWindow.adjustPosition(); 2349 }, 2350 2351 /** 2352 * 2353 * @returns {number} 2354 */ 2355 getPopupPadding: function() { 2356 if (!BX.type.isNumber(this.popupPadding)) 2357 { 2358 if (this.subMenuWindow) 2359 { 2360 var menuContainer = this.subMenuWindow.layout.menuContainer; 2361 this.popupPadding = parseInt(BX.style(menuContainer, "paddingTop"), 10); 2362 } 2363 else 2364 { 2365 this.popupPadding = 0; 2366 } 2367 } 2368 2369 return this.popupPadding; 2370 }, 2371 2372 /** 2373 * 2374 * @returns {BX.PopupMenuWindow|null} 2375 */ 2376 getSubMenu: function() 2377 { 2378 return this.subMenuWindow; 2379 }, 2380 2381 getId: function() 2382 { 2383 return this.id; 2384 }, 2385 2386 /** 2387 * 2388 * @param {BX.PopupMenuWindow} menuWindow 2389 */ 2390 setMenuWindow: function(menuWindow) 2391 { 2392 this.menuWindow = menuWindow; 2393 }, 2394 2395 /** 2396 * 2397 * @returns {BX.PopupMenuWindow} 2398 */ 2399 getMenuWindow: function() 2400 { 2401 return this.menuWindow; 2402 }, 2403 2404 getMenuShowDelay: function() 2405 { 2406 return this.menuShowDelay; 2407 } 2408}; 2409 2410// TODO: copypaste/update/enhance CSS and images from calendar to MAIN CORE 2411// this.values = [{ID: 1, NAME : '111', DESCRIPTION: '111', URL: 'href://...'}] 2412 2413window.BXInputPopup = function(params) 2414{ 2415 this.id = params.id || 'bx-inp-popup-' + Math.round(Math.random() * 1000000); 2416 this.handler = params.handler || false; 2417 this.values = params.values || false; 2418 this.pInput = params.input; 2419 this.bValues = !!this.values; 2420 this.defaultValue = params.defaultValue || ''; 2421 this.openTitle = params.openTitle || ''; 2422 this.className = params.className || ''; 2423 this.noMRclassName = params.noMRclassName || 'ec-no-rm'; 2424 this.emptyClassName = params.noMRclassName || 'ec-label'; 2425 2426 var _this = this; 2427 this.curInd = false;
2428 2429 if (this.bValues) 2430 { 2431 this.pInput.onfocus = this.pInput.onclick = function(e) 2432 { 2433 if (this.value == _this.defaultValue) 2434 { 2435 this.value = ''; 2436 this.className = _this.className; 2437 } 2438 _this.ShowPopup(); 2439 return BX.PreventDefault(e); 2440 }; 2441 this.pInput.onblur = function() 2442 { 2443 if (_this.bShowed) 2444 setTimeout(function(){_this.ClosePopup(true);}, 200); 2445 _this.OnChange(); 2446 }; 2447 } 2448 else 2449 { 2450 this.pInput.className = this.noMRclassName; 2451 this.pInput.onblur = BX.proxy(this.OnChange, this); 2452 } 2453} 2454 2455BXInputPopup.prototype = { 2456ShowPopup: function() 2457{ 2458 if (this.bShowed) 2459 return; 2460 2461 var _this = this; 2462 if (!this.oPopup) 2463 { 2464 var 2465 pRow, 2466 pWnd = BX.create("DIV", {props:{className: "bxecpl-loc-popup " + this.className}}); 2467 2468 for (var i = 0, l = this.values.length; i < l; i++) 2469 { 2470 pRow = pWnd.appendChild(BX.create("DIV", { 2471 props: {id: 'bxecmr_' + i}, 2472 text: this.values[i].NAME, 2473 events: { 2474 mouseover: function(){BX.addClass(this, 'bxecplloc-over');}, 2475 mouseout: function(){BX.removeClass(this, 'bxecplloc-over');}, 2476 click: function() 2477 { 2478 var ind = this.id.substr('bxecmr_'.length); 2479 _this.pInput.value = _this.values[ind].NAME; 2480 _this.curInd = ind; 2481 _this.OnChange(); 2482 _this.ClosePopup(true); 2483 } 2484 } 2485 })); 2486 2487 if (this.values[i].DESCRIPTION) 2488 pRow.title = this.values[i].DESCRIPTION; 2489 if (this.values[i].CLASS_NAME) 2490 BX.addClass(pRow, this.values[i].CLASS_NAME); 2491 2492 if (this.values[i].URL) 2493 pRow.appendChild(BX.create('A', {props: {href: this.values[i].URL, className: 'bxecplloc-view', target: '_blank', title: this.openTitle}})); 2494 } 2495 2496 this.oPopup = new BX.PopupWindow(this.id, this.pInput, { 2497 autoHide : true, 2498 offsetTop : 1, 2499 offsetLeft : 0, 2500 lightShadow : true, 2501 closeByEsc : true, 2502 content : pWnd 2503 }); 2504 2505 BX.addCustomEvent(this.oPopup, 'onPopupClose', BX.proxy(this.ClosePopup, this)); 2506 } 2507 2508 this.oPopup.show(); 2509 this.pInput.select(); 2510 2511 this.bShowed = true; 2512 BX.onCustomEvent(this, 'onInputPopupShow', [this]); 2513}, 2514 2515ClosePopup: function(bClosePopup) 2516{ 2517 this.bShowed = false; 2518 2519 if (this.pInput.value == '') 2520 this.OnChange(); 2521 2522 BX.onCustomEvent(this, 'onInputPopupClose', [this]); 2523 2524 if (bClosePopup === true) 2525 this.oPopup.close(); 2526}, 2527 2528OnChange: function() 2529{ 2530 var val = this.pInput.value; 2531 if (this.bValues) 2532 { 2533 if (this.pInput.value == '' || this.pInput.value == this.defaultValue) 2534 { 2535 this.pInput.value = this.defaultValue; 2536 this.pInput.className = this.emptyClassName; 2537 val = ''; 2538 } 2539 else 2540 { 2541 this.pInput.className = ''; 2542 } 2543 } 2544 2545 if (isNaN(parseInt(this.curInd)) || this.curInd !==false && val != this.values[this.curInd].NAME) 2546 this.curInd = false; 2547 else 2548 this.curInd = parseInt(this.curInd); 2549 2550 BX.onCustomEvent(this, 'onInputPopupChanged', [this, this.curInd, val]); 2551 if (this.handler && typeof this.handler == 'function') 2552 this.handler({ind: this.curInd, value: val}); 2553}, 2554 2555Set: function(ind, val, bOnChange) 2556{ 2557 this.curInd = ind; 2558 if (this.curInd !== false) 2559 this.pInput.value = this.values[this.curInd].NAME; 2560 else 2561 this.pInput.value = val; 2562 2563 if (bOnChange !== false) 2564 this.OnChange(); 2565}, 2566 2567Get: function(ind) 2568{ 2569 var 2570 id = false; 2571 if (typeof ind == 'undefined') 2572 ind = this.curInd; 2573 2574 if (ind !== false && this.values[ind]) 2575 id = this.values[ind].ID; 2576 return id; 2577}, 2578 2579GetIndex: function(id) 2580{ 2581 for (var i = 0, l = this.values.length; i < l; i++) 2582 if (this.values[i].ID == id) 2583 return i; 2584 return false; 2585}, 2586 2587Deactivate: function(bDeactivate) 2588{ 2589 if (this.pInput.value == '' || this.pInput.value == this.defaultValue) 2590 { 2591 if (bDeactivate) 2592 { 2593 this.pInput.value = ''; 2594 this.pInput.className = this.noMRclassName; 2595 } 2596 else if (this.oEC.bUseMR) 2597 { 2598 this.pInput.value = this.defaultValue; 2599 this.pInput.className = this.emptyClassName; 2600 } 2601 } 2602 this.pInput.disabled = bDeactivate; 2603} 2604}; 2605 2606/************** utility *************/ 2607 2608var _escCallbackIndex = -1, 2609 _escCallback = null; 2610 2611function _checkEscPressed(zIndex, callback) 2612{ 2613 if(zIndex === false) 2614 { 2615 if(_escCallback && _escCallback.length > 0) 2616 { 2617 for(var i=0;i<_escCallback.length; i++) 2618 { 2619 _escCallback[i](); 2620 } 2621 2622 _escCallback = null; 2623 _escCallbackIndex = -1; 2624 } 2625 } 2626 else 2627 { 2628 if(_escCallback === null) 2629 { 2630 _escCallback = []; 2631 _escCallbackIndex = -1; 2632 BX.defer(_checkEscPressed)(false); 2633 } 2634 2635 if(zIndex > _escCallbackIndex) 2636 { 2637 _escCallbackIndex = zIndex; 2638 _escCallback = [callback]; 2639 } 2640 else if(zIndex == _escCallbackIndex) 2641 { 2642 _escCallback.push(callback) 2643 } 2644 } 2645} 2646 2647 2648})(window); 2649
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.