nscomponentsreact
Version:
React Wrapper Components for NSComponents
746 lines (704 loc) • 21.9 kB
JavaScript
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);