/*
**YUI 3.6.0 based custome module AHDialog to resolve the problem of responsive dialog/panel/modal**
*/
//Creating Custom Modules with YUI Using the YUI Module Control
//YUI add is a method on the YUI global, not on the YUI instance.
//Registers a module with the YUI global. The easiest way to create a first-class YUI module is to use the YUI component build tool.
//The build system will produce the YUI.add wrapper for you module, along with any configuration info required for the module.
//ref URL - http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_add
YUI.add('AHDialog', function (Y) {
var getClassName = Y.ClassNameManager.getClassName;
/*
Widget is the foundation class from which all YUI 3 widgets are derived. It provides the following pieces of core functionality on top
of what Base already provides:
*Adds the render lifecycle moment, to Base's init and destroy moments
*Abstract rendering methods to promote a consistent MVC pattern across widgets
*A common set of widget attributes
*Consistent markup generation support
*Consistent class-name generation support
*Built-in progressive enhancement support
*As you start to develop widgets in YUI 3, there are a number of extensions packaged as part of the library which you can use with Base.
build (or Base.create, Base.mix) to add functionality to your custom widget classes:
*ref URL - http://yuilibrary.com/yui/docs/widget/
*/
//Create panle widget using Y.Base.create
//Extensions are applied to a class using the static Base.build method (or the Base.create or Base.mix sugar methods which sit on top of Base.build)
//to read more - http://yuilibrary.com/yui/docs/widget/
/*
Extension and - Functionality:
widget-position -Adds XY positioning support to the class.
widget-position-align -Adds XY aligned positioning support to the class.
widget-position-constrain -Adds constrained XY positioning support to the class.
widget-stack -Adds stacking (zIndex) support to the class.
widget-stdmod -Adds Standard Module (header, body, footer) support to the class.
widget-parent -Adds support to allow the widget to contain, manage and select child widgets.
widget-child -Adds support to allow the widget to be contained within a widget parent.
widget-buttons -Adds header/body/footer buttons support for Widgets that use the WidgetStdMod extension.
widget-autohide -Adds support to hide the widget when certain DOM events occur.
widget-modality -Adds support for modality to widgets.
*/
Y.AHDialog = Y.Base.create('AHDialog', Y.Widget, [
// Other Widget extensions depend on these two.
Y.WidgetPosition,
Y.WidgetStdMod,
Y.WidgetAutohide,
/*Y.WidgetButtons,*/
Y.WidgetModality,
Y.WidgetPositionAlign,
Y.WidgetPositionConstrain,
Y.WidgetStack],
/*
//Default widget button attributes
//Adds a button to this widget.
//The new button node will have the Y.Plugin.Button plugin applied, be added to this widget's buttons,
//and rendered in the specified section at the specified index (or end of the section when no index is provided). If the section does not exist, it will be created.
//ref URL - http://yuilibrary.com/yui/docs/api/classes/WidgetButtons.html#method_addButton
{
BUTTONS: {
close: {
label : 'Close',
action : 'hide',
section: 'header',
// Uses `type="button"` so the button's default action can still
// occur but it won't cause things like a form to submit.
template : '',
classNames: getClassName('button', 'close')
}
}
},
{
ATTRS: {
buttons: {
value: ['close']
}
}
},
*/
//render UI function to do math and set properties to dialog to attach in particular element/node.
//and render the code in widget.render() function
/*
*This method is responsible for creating and adding the nodes which the widget needs into the document
*(or modifying existing nodes, in the case of progressive enhancement).
*It is usually the point at which the DOM is first modified by the widget.
*/ {
initializer: function (config) {
this._containerNodeID = config.id;
this._isFlyout = config.isFlyout;
this._buttons = config.buttons;
this._isFlyoutClosed = false;
this._containerNodeWidth = config.width;
},
renderUI: function () {
var instance = this;
var boundingBox = this.get('boundingBox');
var dialogWidth = boundingBox.get('offsetWidth');
var AHDialogWidth = this.get('width');
/*
//most of the logic written for boundingBox which is container of our AHDialog.
*The bounding box is the outermost element owned by the widget and is used for functional, rather than visual, purposes:
*A class name identifying the widget is added to the bounding box.
*Additionally, class names for all widget classes in the class hierarchy are also used to tag the bounding box.
*Class names used for state management by the widget instance are also applied to the bounding box.
*The widget's width and height values are applied to the bounding box if set, as are top/left (xy) positioning values, for positioned widgets.
*The bounding box is not expected to have any visual properties (e.g. borders, padding, etc.) applied to it.
*/
boundingBox.setAttribute('id', this._containerNodeID);
this._containerNode = Y.one("#"+this._containerNodeID);
boundingBox.setStyle('position', 'fixed');
boundingBox.addClass('hidden');
if(this._isFlyout){
boundingBox.addClass('ah-gmc-popover-flyout').removeClass('yui3-ahdialog');
boundingBox.one(".yui3-ahdialog-content.yui3-widget-stdmod").addClass('clearfix');
boundingBox.one(".yui3-widget-stdmod .yui3-widget-bd").addClass('ah-gmc-inner-wrapper');
boundingBox.one(".yui3-widget-stdmod .yui3-widget-bd").addClass('clearfix');
boundingBox.setStyle('position', 'absolute');
boundingBox.setStyle('zIndex', '999999');
}
/*Removed '' from below line to handle it from CSS*/
if(this._isFlyout){
boundingBox.prepend('
'+closeWindowTxt+'
');
} else {
boundingBox.prepend('
'+closeWindowTxt+'
');
}
//Close button Listener
var closeBtn = Y.one('#ahDialogCloseBtn');
var AHDialog = this._containerNode;
closeBtn.on('keydown', function (e) {
if(e.keyCode == '13'){
closeBtn.simulate("click");
}
});
closeBtn.on('click', function (e) {
if(Y.one('html')){
Y.one('html').setStyle('minHeight', '');
};
if(Y.one('#ah-header nav')){
Y.one('#ah-header nav').setStyle('position', '');
Y.one('#ah-header nav').setStyle('zIndex', '');
};
AUI().use('anim', function(A){
var flyoutMask1 = A.one('#ah-gmc-messages-link .yui3-widget-mask');
if(flyoutMask1){
var fadeAnim = new A.Anim({
node: flyoutMask1,
to:{
opacity: 0
},
duration: .5
});
fadeAnim.run();
};
/*
A.setTimeout(function(){
boundingBox.addClass('hidden');
A.one('#ah-gmc-messages-link .yui3-widget-mask').addClass("aui-overlaymask-hidden");
}, 500);
*/
A.later(500, window, function(){
boundingBox.addClass('hidden');
A.one('#ah-gmc-messages-link .yui3-widget-mask').addClass("aui-overlaymask-hidden");
}, [], false);
});
this._isFlyoutClosed = true;
this._isFlyout = false;
instance.hide();
});
/* TODO: Found following line from version 5 not sure of sandeep's POC not sure which line to use */
var width = this._containerNode.get('offsetWidth');
var left = "-" + width;
var AHPWidth = this._containerNode.getStyle('width');
//Window resize function to check document size and change the dialog width if its less than 720px.
//this we can define on YUI().use so that user can define viewport, dialog width & other properties if required
if(this._buttons){
this.addButtons();
}
},
//SetTopLeft to remove top and left style value
setTopLeft: function () {
this.get('boundingBox').setStyles({
left: '',
top: ''
});
}, //setTopLeft end
//responsive function to act responsive in all viewport
responsive: function () {
var instance = this;
var boundingBox = this._containerNode;
if (boundingBox.getStyle('top').replace('px', '') < 1) {
boundingBox.setStyle('top', 10);
}
Y.on('windowresize', function () {
var boundingBox = instance._containerNode;
//var windowSize=Y.one("body").get("winWidth");
//var windowHeight=Y.one("body").get("winHeight");
var dialogWidth = boundingBox.get('offsetWidth');
var dialogHeight = boundingBox.get('offsetHeight');
var myWidth = 0,
myHeight = 0;
if (typeof (window.innerWidth) == 'number') {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
//var x = (myWidth / 2) - (dialogWidth / 2) - 8;
//var y = (myHeight / 2) - (dialogHeight / 2) - 8;
var x = ((myWidth - dialogWidth) / 2) - 10;
var y = ((myHeight - dialogHeight) / 2) - 10;
if (y > 0) {
boundingBox.setStyle('top', y);
boundingBox.setStyle('left', x);
}
});
}, //setTopLeft end
//windowResize function to resize the dialog width according to given viewport
windowResize: function (viewport, viewportwidth) {
var instance = this;
//when screensize in less than 'viewport' change AHDialog width into percentage
var AHDialog = this._containerNode;
AHDialog.setStyle('width', 0);
var windowSize = Y.one("body").get("winWidth");
var AHDialogWidth = this._containerNodeWidth;
var dialogWidth = ((windowSize * AHDialogWidth) / 100);
var viewportwidthSet = ((windowSize * viewportwidth) / 100) - 30;
var flyoutWidth = 0;
if (windowSize <= viewport) {
AHDialog.setStyles({
width: parseInt(viewportwidthSet),
float: 'right'
})
flyoutWidth = parseInt(viewportwidthSet);
} else {
//here user can define AHDialog with
AHDialog.setStyle('width', parseInt(dialogWidth));
flyoutWidth = parseInt(dialogWidth);
}
//on screensize change event
//when screensize in less than 720 change AHDialog width into percentage
Y.on('windowresize', function () {
var windowSize = Y.one("body").get("winWidth");
var viewportwidthSet = ((windowSize * viewportwidth) / 100) - 30;
var dialogWidth = ((windowSize * AHDialogWidth) / 100);
var flyoutWidth = 0;
if (windowSize <= viewport) {
AHDialog.setStyles({
width: parseInt(viewportwidthSet),
float: 'right'
})
flyoutWidth = parseInt(viewportwidthSet);
} else {
//here user can define AHDialog with
AHDialog.setStyle('width', parseInt(dialogWidth));
flyoutWidth = parseInt(dialogWidth);
}
//AHDialog.setStyle('right', '');
//AHDialog.setStyle('right', AHDialog.getStyle('right'));
instance.flyoutHeight(flyoutWidth);
});
instance.flyoutHeight(flyoutWidth);
}, //windowResize end
hide : function(){
this._containerNode.hide();
if(Y.one('.yui3-widget-mask')){
/*Y.one('.yui3-widget-mask').hide();*/
}
},
bindUI: function () {
}, //bindUI end
syncUI: function () {
//SyncUI
var instance = this;
var boundingBox = this.get('boundingBox');
if(this._isFlyout){
AUI().use('node', 'anim', function(A){
var flyoutMask = A.one('#ah-gmc-messages-link .yui3-widget-mask');
if(flyoutMask){
var fadeAnim = new A.Anim({
node: flyoutMask,
to:{
opacity: .5
},
duration: 1
});
fadeAnim.run();
flyoutMask.setStyle('zIndex', '9999');
};
/*
A.setTimeout(function(){
boundingBox.removeClass('hidden');
}, 400);
*/
A.later(400, window, function(){
boundingBox.removeClass('hidden');
}, [], false);
});
};
//this.flyoutHeight();
}, //syncUI end
flyoutHeight : function(flyoutWidth){
if(this._isFlyout){
Y.one('html').setStyle('minHeight', '');
var instance = this;
var boundingBox = this.get('boundingBox');
var headerHegiht = 0;
//alert(flyoutWidth);
boundingBoxHeight = parseInt(boundingBox.getStyle('height'));
bodyHeight = parseInt(Y.one('html').getStyle('height'));
if(Y.one('#ah-header')){
headerHegiht = parseInt(Y.one('#ah-header').getStyle('height'));
};
//overlayHeight = (bodyHeight + boundingBoxHeight) - headerHegiht + 20;
overlayHeight = boundingBoxHeight + headerHegiht + 70;
if(Y.one('html')){
Y.one('html').setStyle('minHeight', overlayHeight);
}
if(Y.one('#ah-gmc-messages-link .yui3-widget-mask')){
Y.one('#ah-gmc-messages-link .yui3-widget-mask').setStyle('zIndex', '9999');
}
boundingBox.setStyle('zIndex', '999999');
boundingBox.focus();
if(Y.one('#ah-header nav')){
Y.one('#ah-header nav').setStyle('position', 'relative');
Y.one('#ah-header nav').setStyle('zIndex', '3010');
}
/* flyout alignment above 960 view */
badgeIconWidth = 0;
if(Y.one("#ah-gmc-messages-link")){
badgeIconWidth = parseInt(Y.one("#ah-gmc-messages-link").getStyle('width')) / 2;
badgeIconX = Y.one("#ah-gmc-messages-link").getX();
Y.one("#ah-gmc-messages-link #badgeCnt").setStyle('position', 'relative');
}
//flyoutPos = badgeIconWidth - (flyoutWidth * 90 / 100) - 10;
//flyoutPos = badgeIconWidth - (boundingBox.get("offsetWidth") * 10 / 100) - 12;
//boundingBox.setStyle('left', parseInt(flyoutPos));
//boundingBox.setStyle('right', '');
if(Y.one('html').hasClass('rtl')){
flyoutPos = badgeIconWidth - (flyoutWidth * 10 / 100) + 10;
boundingBox.setStyle('left', parseInt(flyoutPos));
boundingBox.setStyle('right', 'auto');
} else {
flyoutPos = badgeIconWidth - (flyoutWidth * 90 / 100) - 10;
boundingBox.setStyle('left', parseInt(flyoutPos));
boundingBox.setStyle('right', '');
}
if(Y.one('html').hasClass('touch')){
Y.on('scroll', this._resyncMask);
};
};
},
_resyncMask: function (e) {
var maskObject = Y.one('#ah-gmc-messages-link .yui3-widget-mask');
if(maskObject){
maskObject.setStyles({
width: '100%',
Height: '100%',
left: '0',
top: '0'
});
};
},
/*
Following methods adding buttons to widget dom.
This temp method added as button widget of YUI3.4.0 is not as per requirement.
We can remove following method when liferay upgrades to YUI 3.5.x
*/
addButtons : function(){
var instance = this;
if(instance._containerNode.all(".yui3-widget-stdmod .yui3-widget-ft").size() == 0){
instance._containerNode.one(".yui3-widget-stdmod").append("");
}
if(instance._containerNode.all(".yui3-widget-stdmod .yui3-widget-hd").size() == 0){
instance._containerNode.one(".yui3-widget-stdmod").append("");
}
instance._footerNode = instance._containerNode.one(".yui3-widget-stdmod .yui3-widget-ft");
instance._headerNode = instance._containerNode.one(".yui3-widget-stdmod .yui3-widget-hd");
Y.each(this._buttons,function(buttons,sectionName){
for (var i=0;i";
var bt = Y.Node.create(btHTML);
if(buttons[i].events){
Y.each(buttons[i].events,function(eventHandler,eventName){
bt.on(eventName,eventHandler);
});
}
if(sectionName && sectionName.toLowerCase() == "footer"){
instance._footerNode.append(bt)
}else if(sectionName && sectionName.toLowerCase() == "header"){
instance._headerNode.append(bt)
}
}
});
}
}, //Widget end
//viewport function is to define panle properties based on define viewports
//that user can call on the page
{
_viewport: function () {
var windowSize = Y.one("body").get("winWidth");
if (windowSize <= 720) {
//alert(windowSize);
//boundingBox.setStyles({width: 80+'%',float: 'right'})
}
}
},
{
});
//Require values for widget
/*
*The add() method accepts two optional arguments after the callback function: a module version string and a config object.
*The most useful option in the config object is requires, which allows you to specify an array of other YUI modules that your module requires.
*YUI will then be sure to load these dependencies before executing your module.
*/
}, '1.0.0', {
requires: ['widget', 'widget-autohide', 'widget-buttons', 'widget-modality', 'widget-position', 'widget-position-align', 'widget-position-constrain', 'widget-stack', 'widget-stdmod', 'anim','event', 'node-event-simulate','event-key']
});