UNPKG

nscomponentsreact

Version:

React Wrapper Components for NSComponents

746 lines (704 loc) 21.9 kB
var nsModuleExport = function(root,name,prototype) { if(typeof exports === 'object' && typeof module === 'object') { module.exports[name] = prototype; } else if (typeof define === "function" && define.amd) { define(name,[], function () {return prototype;}); } else if(typeof exports === 'object') { exports[name] = prototype; } else { root[name] = prototype; } };var __nsGlobal = (function () { if (typeof globalThis !== "undefined") return globalThis; if (typeof self !== "undefined") return self; if (typeof window !== "undefined") return window; if (typeof global !== "undefined") return global; return Function("return this")(); })();var nsIsWeb = function(root) { if(typeof exports === 'object' && typeof module === 'object') { return false; } else if (typeof define === "function" && define.amd) { return false; } else if(typeof exports === 'object') { return false; } else { return true; } };if(!nsIsWeb()) { var nsutilRef = require('./nsUtil.min.js'); var NSUtil = nsutilRef.NSUtil; } "use strict"; var NSPinTip = (function() { function NSPinTip(component,option) { this.__component = component; this.__setting = option; this.__config = {}; this.__id = null; this.__divTipContainer = null; this.__divTipHeader = null; this.__divTip = null; this.__divTipArrow = null; this.__itemRenderer = null; this.__currentPosition = null; this.__isVisible = false; this.__showCalled = false; this.__styleSuffix = "nsPinTip"; this.util = null; this.__componentMouseOverRef = null; this.__componentMouseOutRef = null; this.__windowResizeRef = null; this.__windowScrollRef = null; this.__documentClickHandlerRef = null; this.__initialize(); }; NSPinTip.prototype.show = function(text) { this.__showCalled = true; var self = this; var afterShow = function() { self.__isVisible = true; if(self.__config["closeOnOutsideClick"]) { var clickHandler = self.__popUpClickHandler.bind(self); self.util.addEvent(self.__divTipContainer,"click",clickHandler); if(!self.__documentClickHandlerRef) { self.__documentClickHandlerRef = self.__documentClickHandler.bind(self); self.util.addEvent(document,"click",self.__documentClickHandlerRef); } } }; if(text) { this.__config.text = text; } if(this.__config.text || this.__config.template || this.__config.renderer) { if(!this.__divTipContainer) { this.__currentPosition = this.__config.position; this.__createTip(this.__config.position); } if(this.__config.enableAnimation) { this.util.fadeIn(this.__divTipContainer,null,function(component) { afterShow(); }); } else { this.util.removeStyleClass(this.__divTipContainer,this.__getStyleName("hide")); afterShow(); } this.__addContent(); this.__placeTip(this.__config.position); } }; NSPinTip.prototype.remove = function() { var self = this; var fireEvent = function() { self.__removeDocEvent(); self.__dispatchEvent.call(self,NSPinTip.CLOSED); }; if(this.__config.enableAnimation) { var objPinTip = this; this.util.fadeOut(this.__divTipContainer,function(component) { if(this.__divTipContainer) { document.body.removeChild(objPinTip.__divTipContainer); objPinTip.__divTipContainer = null; objPinTip.__isVisible = false; fireEvent(); } }); } else { if(this.__divTipContainer) { document.body.removeChild(this.__divTipContainer); this.__divTipContainer = null; this.__isVisible = false; fireEvent(); } } }; NSPinTip.prototype.hide = function() { var self = this; var fireEvent = function() { self.__removeDocEvent(); self.__dispatchEvent.call(self,NSPinTip.HIDDEN); }; if(this.__config.enableAnimation) { var objPinTip = this; this.util.fadeOut(this.__divTipContainer,function(component) { objPinTip.__isVisible = false; fireEvent(); }); } else { this.util.addStyleClass(this.__divTipContainer,this.__getStyleName("hide")); this.__isVisible = false; fireEvent(); } }; NSPinTip.prototype.setTheme = function(theme) { if(theme) { this.util.removeStyleClass(this.__divTipContainer, "nsPinTip" + this.__config.theme); this.__config.theme = theme; this.util.addStyleClass(this.__divTipContainer, "nsPinTip" + this.__config.theme); } }; NSPinTip.prototype.destroyObject = function() { if(this.__componentMouseOverRef) { this.util.removeEvent(this.__component,"mouseover",this.__componentMouseOverRef); this.__componentMouseOverRef = null; } if(this.__componentMouseOutRef) { this.util.removeEvent(this.__component,"mouseout",this.__componentMouseOutRef); this.__componentMouseOutRef = null; } if(this.__windowResizeRef) { this.util.removeEvent(window,"resize",this.__windowResizeRef); this.__windowResizeRef = null; } if(this.__windowScrollRef) { this.util.removeEvent(document,"scroll",this.__windowScrollRef,true); this.__windowScrollRef = null; } this.__removeDocEvent(); }; NSPinTip.prototype.isVisible = function() { return this.__isVisible; }; NSPinTip.prototype.__initialize = function(properties) { this.util = new NSUtil(); var setting = this.__setting; if(!setting) { setting = {}; } this.__config = { position: setting["position"] || this.util.POS_BOTTOM, size: setting["size"] || NSPinTip.SIZE_MEDIUM, showOnMouseHover: this.util.isUndefinedOrNull(setting["showOnMouseHover"]) ? true : Boolean.parse(setting["showOnMouseHover"]), text: setting["text"], renderer: setting["renderer"], template: setting["template"], style: setting["style"], enableAnimation: Boolean.parse(setting["enableAnimation"]), theme: this.__setting["theme"] || "Black",// default theme is black as it looks for tooltip showEvent: setting["showEvent"], hideEvent: setting["hideEvent"], hideOrRemoveAutomatic: setting["hideOrRemoveAutomatic"] || "remove", closeOnOutsideClick: Boolean.parse(setting["closeOnOutsideClick"]), title: setting["title"], closeRequired: Boolean.parse(setting["closeRequired"]), closeHtml: setting["closeHtml"] || "<span class=\"nsPopUpClose\"></span>", showInitially: Boolean.parse(setting["showInitially"]), closeOnScroll: Boolean.parse(setting["closeOnScroll"]) }; if(!setting.customClass) { setting.customClass = {}; } var customClass = setting.customClass; this.__config.customClass = { headerContainer: customClass["headerContainer"], title: customClass["title"], close: customClass["close"], body: customClass["body"] }; this.__config.position = this.__config.position.toLowerCase(); this.__config.size = this.__config.size.toLowerCase(); if(this.__config.showOnMouseHover) { this.__config.showEvent = "mouseover"; this.__config.hideEvent = "mouseout"; } if(this.__config.showEvent) { this.__componentMouseOverRef = this.__componentMouseOverHandler.bind(this); this.util.addEvent(this.__component,this.__config.showEvent,this.__componentMouseOverRef); } if(this.__config.hideEvent) { this.__componentMouseOutRef = this.__componentMouseOutHandler.bind(this); this.util.addEvent(this.__component,this.__config.hideEvent,this.__componentMouseOutRef); } this.__windowResizeRef = this.__windowResizeHandler.bind(this); this.__windowScrollRef = this.__windowScrollHandler.bind(this); this.util.addEvent(window,"resize",this.__windowResizeRef); if(this.__config.closeOnScroll) { this.util.addEvent(document,"scroll",this.__windowScrollRef,true);//using capture phase so that any child in dom scrolls this scroll listener will get fired } if(this.__config.showInitially) { this.show(); } }; NSPinTip.prototype.__createTip = function(position) { if(!this.__divTipContainer) { this.__divTipContainer = this.util.createDiv(this.__getID() + "#nsTipContainer",null); this.__setTipStyle(position); if(this.__config["title"] || this.__config["closeRequired"]) { this.__divTipContainer.style.minHeight = "50px"; var divHead = this.util.createDiv(null,"nsPopUpHeader"); this.__divTipHeader = this.util.createDiv(null,"nsPopUpHeaderContainer"); this.__applyCustomClass(this.__divTipHeader,"headerContainer"); var divTitleContainer = this.util.createDiv(null,"nsPopUpTitleContainer"); this.__applyCustomClass(divTitleContainer,"title"); if(this.__config["title"]) { var divTitle = this.util.createDiv(null,"nsPopUpTitle"); divTitle.innerHTML = this.__config["title"]; divTitleContainer.appendChild(divTitle); } this.__divTipHeader.appendChild(divTitleContainer); var divCloseContainer = this.util.createDiv(null,"nsPopUpCloseContainer"); this.__applyCustomClass(divCloseContainer,"close"); if(this.__config["closeRequired"]) { var btnTitle = this.util.createElement("button",null,"nsPopUpBtnClose"); divCloseContainer.appendChild(btnTitle); btnTitle.innerHTML = this.__config["closeHtml"]; var self = this; this.util.addEvent(btnTitle,"click",function(event){ self.__closeHandler.call(self,event); }); } this.__divTipHeader.appendChild(divCloseContainer); divHead.appendChild(this.__divTipHeader); this.__divTipContainer.appendChild(divHead); } this.__divTipArrow = this.util.createDiv(this.__getID() + "#nsTipArrow", this.__getStyleName("arrow")); this.__divTipContainer.appendChild(this.__divTipArrow); this.__divTip = this.util.createDiv(this.__getID() + "#nsTip",this.__getStyleName("content")); this.__applyCustomClass(this.__divTip,"body"); this.__divTipContainer.appendChild(this.__divTip); this.__applyExtraStyle(); document.body.appendChild(this.__divTipContainer); } }; NSPinTip.prototype.__popUpClickHandler = function(event) { event.stopPropagation(); }; NSPinTip.prototype.__documentClickHandler = function(event) { event = this.util.getEvent(event); var target = event.target; if(target != this.__component && !this.__divTipContainer.contains(target)) { this.__closeHandler(event); } }; NSPinTip.prototype.__placeTip = function(position) { var offset = this.__getOffset(position); var newPosition = this.__getSuggestedPosition(position, offset); if (newPosition && newPosition !== position) { position = newPosition; offset = this.__getOffset(position); } this.__currentPosition = position; this.__setTipStyle(position); this.__divTipContainer.style.top = offset.top + "px"; this.__divTipContainer.style.left = offset.left + "px"; }; NSPinTip.prototype.__addContent = function() { this.util.removeAllChildren(this.__divTip); if(this.__config.template) { if(!this.__itemRenderer) { this.__itemRenderer = this.util.getTemplate(this.__config.template); } if(this.__itemRenderer) { this.__divTip.appendChild(this.__itemRenderer.cloneNode(true)); } } else if(this.__config.renderer) { var objRenderer = this.__config.renderer(this.__component,this.__setting); if(objRenderer) { if(this.util.isString(objRenderer)) { var compSpan = document.createElement("span"); compSpan.innerHTML = objRenderer; this.__divTip.appendChild(compSpan); } else { this.__divTip.appendChild(objRenderer); } } } else if(this.__config.text) { if(this.util.isString(this.__config.text)) { this.__divTip.innerHTML = this.__config.text; } else { this.util.warning("NSPinTip","text is not a string."); } } }; NSPinTip.prototype.__applyExtraStyle = function() { if(this.__config.style && this.util.isString(this.__config.style) && this.__config.style != "") { var arrStyles = this.__config.style.split(";"); if(arrStyles && arrStyles.length > 0) { var clonedContainer = this.__divTipContainer.cloneNode(true); clonedContainer.style.position = "absolute"; clonedContainer.style.left = "-10000em"; clonedContainer.style.top = "-10000em"; clonedContainer.style.display = "block"; document.body.appendChild(clonedContainer); var containerRect = clonedContainer.getBoundingClientRect(); var headerRect = this.__divTipHeader ? clonedContainer.querySelector(".nsPopUpHeaderContainer").getBoundingClientRect() : null; var bodyRect = clonedContainer.querySelector("." + this.__getStyleName("content")).getBoundingClientRect(); document.body.removeChild(clonedContainer); for(var count = 0; count < arrStyles.length;count++) { var arrStyle = arrStyles[count].split(":"); if(arrStyle && arrStyle.length === 2) { var styleProp = this.util.convertCSSPropToJS(arrStyle[0]); var styleValue = arrStyle[1]; var setValue = true; switch(styleProp) { case "backgroundColor": var propPos = null; if(this.__currentPosition.indexOf(this.util.POS_TOP) > -1) { propPos = this.util.POS_TOP; } else if(this.__currentPosition.indexOf(this.util.POS_BOTTOM) > -1) { propPos = this.util.POS_BOTTOM; } else if(this.__currentPosition.indexOf(this.util.POS_LEFT) > -1) { propPos = this.util.POS_LEFT; } else if(this.__currentPosition.indexOf(this.util.POS_RIGHT) > -1) { propPos = this.util.POS_RIGHT; } if(propPos) { propPos = propPos[0].toUpperCase() + propPos.slice(1); } this.__divTipArrow.style["border" + propPos + "Color"] = styleValue; break; case "height": var orignalHeight = this.util.getDimensionAsNumber(this.__divTipContainer,styleValue); var height = orignalHeight; if(headerRect) { height = height - headerRect.height; } if(height > 0) { this.__divTip.style.height = height + "px"; } if(orignalHeight > 0) { //this.__divTipContainer.style.height = orignalHeight + "px"; } setValue = false; break; case "width": var width = this.util.getDimensionAsNumber(this.__divTipContainer,styleValue); if(width > 0) { this.__divTipContainer.style.width = width + "px"; } setValue = false; break; } if(setValue) { this.__divTip.style[styleProp] = styleValue; } } } } } }; NSPinTip.prototype.__getOffset = function(position) { var pad = 15; var rectTip = this.__divTipContainer.getBoundingClientRect(); var rectComponent = this.__component.getBoundingClientRect(); var item = {top: 0,left:0}; if(rectTip && rectComponent) { var tipWidth = rectTip.width; var tipHeight = rectTip.height; var componentWidth = rectComponent.width; var componentHeight = rectComponent.height; var componentOffset = this.util.getOffSetForElementRectangle(rectComponent); switch(position) { case this.util.POS_TOP: item.top = componentOffset.top - tipHeight; item.left = componentOffset.left + componentWidth / 2 - tipWidth / 2; break; case this.util.POS_BOTTOM: item.top = componentOffset.top + componentHeight; item.left = componentOffset.left + componentWidth / 2 - tipWidth / 2; break; case this.util.POS_LEFT: item.top = componentOffset.top + componentHeight / 2 - tipHeight / 2; item.left = componentOffset.left - tipWidth; break; case this.util.POS_RIGHT: item.top = componentOffset.top + componentHeight / 2 - tipHeight / 2, item.left = componentOffset.left + componentWidth; break; case this.util.POS_TOPLEFT: item.top = componentOffset.top - tipHeight; item.left = componentOffset.left + componentWidth / 2 - tipWidth + pad; break; case this.util.POS_TOPRIGHT: item.top = componentOffset.top - tipHeight; item.left = componentOffset.left + componentWidth / 2 - pad; break; case this.util.POS_BOTTOMLEFT: item.top = componentOffset.top + componentHeight; item.left = componentOffset.left + componentWidth / 2 - tipWidth + pad; break; case this.util.POS_BOTTOMRIGHT: item.top = componentOffset.top + componentHeight; item.left = componentOffset.left + componentWidth / 2 - pad; break; } } return item; }; NSPinTip.prototype.__getSuggestedPosition = function(position,offset) { var tipWidth = this.__divTipContainer.clientWidth; var tipHeight = this.__divTipContainer.clientHeight; var top = window.scrollY; var left = window.scrollX; var totalWidth = window.innerWidth; var totalHeight = window.innerHeight; var objPosition = {}; objPosition[this.util.POS_TOP] = true; objPosition[this.util.POS_BOTTOM] = true; objPosition[this.util.POS_LEFT] = true; objPosition[this.util.POS_RIGHT] = true; if (offset.top < top) { objPosition[this.util.POS_TOP] = false; } if (offset.top + tipHeight > top + totalHeight) { objPosition[this.util.POS_BOTTOM] = false; } if (offset.left < left) { objPosition[this.util.POS_LEFT] = false; } if (offset.left + tipWidth > left + totalWidth) { objPosition[this.util.POS_RIGHT] = false; } var positions = position.split("-"); //below loop tries to give favourable position like bottom-right so if position has bottom and right both true it returns that position for (var count = 0; count < positions.length; count++) { if (!objPosition[positions[count]]) { break; } if (count === positions.length - 1) { return position; } } //below loop tries to give one favourable position like in bottom-right if bottom is true or right is true it gets returned for (var count = 0; count < positions.length; count++) { if (objPosition[positions[count]]) { return positions[count]; } } if (objPosition[position]) { return position; } for(var tmpPosition in objPosition) { if (objPosition[tmpPosition]) { return tmpPosition; } } }; NSPinTip.prototype.__componentMouseOverHandler = function(event) { event = this.util.getEvent(event); this.show(this.__config.text); event.stopPropagation(); event.preventDefault(); }; NSPinTip.prototype.__componentMouseOutHandler = function(event) { event = this.util.getEvent(event); this.__closeHandler(event); event.preventDefault(); }; NSPinTip.prototype.__windowScrollHandler = function(event) { if(!this.__showCalled) { if(this.isVisible()) { this.__closeHandler(); } this.__dispatchEvent(NSPinTip.SCROLLED); } this.__showCalled = false; }; NSPinTip.prototype.__windowResizeHandler = function(event) { if(this.isVisible()) { this.show(this.__config.text); } this.__dispatchEvent(NSPinTip.RESIZED); }; NSPinTip.prototype.__closeHandler = function(event) { if(this.__config.hideOrRemoveAutomatic == "remove") { this.remove(); } else { this.hide(); } }; NSPinTip.prototype.__removeDocEvent = function() { if(this.__documentClickHandlerRef) { this.util.removeEvent(document,"click",this.__documentClickHandlerRef); this.__documentClickHandlerRef = null; } }; NSPinTip.prototype.__dispatchEvent = function(eventType,data,param,bubbles,cancelable) { this.util.dispatchEvent(this.__component,eventType,data,param,bubbles,cancelable); }; NSPinTip.prototype.__setTipStyle = function(position) { var classname = this.__styleSuffix; var posStyle = this.__getStyleName(position.toLowerCase()); if(!posStyle) { posStyle = this.__getStyleName("top"); } classname += " " + posStyle; classname += " " + this.__getStyleName(this.__config.size); this.__divTipContainer.setAttribute("class", classname); this.setTheme(this.__config.theme); }; NSPinTip.prototype.__applyCustomClass = function(element,type) { if(element && type && this.__config.customClass[type]) { this.util.addStyleClass(element,this.__config.customClass[type]); } }; NSPinTip.prototype.__getStyleName = function(styleName) { return this.__styleSuffix + "-" + styleName; }; NSPinTip.prototype.__getID = function() { if(!this.__id) { if(this.__component.hasAttribute("id")) { this.__id = this.__component.getAttribute("id"); } else if(this.__component.hasAttribute("name")) { this.__id = this.__component.getAttribute("name"); } else { this.__id = "comp" + this.util.getUniqueId(); } } return this.__id; }; NSPinTip.SIZE_LARGE = "large"; NSPinTip.SIZE_MEDIUM = "medium"; NSPinTip.SIZE_LOW = "low"; NSPinTip.CLOSED = "closed"; NSPinTip.HIDDEN = "hidden"; NSPinTip.SCROLLED = "scrolled"; NSPinTip.RESIZED = "resized"; return NSPinTip; })(); nsModuleExport(__nsGlobal,"NSPinTip",NSPinTip);