dojo.provide("epages.widget.Modaldialog");
dojo.require("epages.widget.LocalizedWidget");
dojo.require("epages.browser");
dojo.require("epages.template");
dojo.require("epages.html");
dojo.require("epages.event");
dojo["require"]('dijit.Dialog'); //change require syntax to keep it here after shrinksafe
dojo.require('dojox.layout.ContentPane');
dojo.require('epages.lang.hash');
dojo.require('epages.io.text');
dojo.require('epages.widget.Button');
dojo.declare(
"epages.widget.Modaldialog",
[dijit.Dialog, epages.widget.LocalizedWidget],
{
/**
* public properties
*/
buttons: undefined,
options: undefined,
duration: epages.Browser.engine=="MSIE" ? 10 : 150,
title: '',
'class' : '',
/**
* private properties
*/
_contentWidget: null,
_contentPane: null,
_events: null,
_tabEvents: null,
_tabs: undefined,
_currentTab: undefined,
_iframe: null,
_doc: null,
/**
* dojo widget properties
*/
translationName : dojo.moduleUrl('epages.widget', "templates/translation"),
imagePath : epages.themeUrl('images'),
buttonTemplateString : '<span class="Button EnableHover (%Class%)" (%buttonId%)><span class="ButtonContainer">(%Label%)</span></span>',
tabTemplateString : '<div class="Tab"><div>(%Label%)</div></div>',
innerTemplatePath : null,
widgetsInTemplate : true,
templateString: dojo.cache("epages.widget", "templates/Modaldialog.html"),
clearFloatNode : undefined,
buildRendering: function() {
// summary:
// replaces the placeholder in the base template with the template from innerTemplateString,
// so this works like an include and you don't have to rewrite the whole template in sub-
// classes.
if (this.innerTemplatePath != null) {
this.templateString = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, true);
var innerTemplateString = dijit._Templated.getCachedTemplate(this.innerTemplatePath, null, true);
this.templateString = this.templateString.replace('<!-- //innerTemplate// -->', innerTemplateString);
this.templatePath = '';
}
this.inherited("buildRendering", arguments);
},
postMixInProperties: function() {
var options = {containerClass: ''};
dojo.mixin(options, this.options);
this.options = options;
dijit.Dialog.prototype.postMixInProperties.apply(this, arguments);
this.inherited("postMixInProperties", arguments);
},
postCreate: function() {
this._doc = this.domNode.ownerDocument;
//call postCreate of dijit.dialog because this.inherited only references to the last parent class
dijit.Dialog.prototype.postCreate.apply(this, arguments);
this.inherited("postCreate", arguments);
if(this.buttons===undefined){
this.buttons=[];
}
if(this.tabs===undefined){
this.tabs=[];
}
if(this.options===undefined){
this.options={};
}
this._createContent(this.options);
this._createButtons(this.buttons);
this._createTabs();
dojo.addClass(this.domNode, this['class']);
dojo.subscribe(this.id+"/executeAction",dojo.hitch(this,this.executeAction));
},
executeAction : function(/*String*/ functionName,/*anything...*/additionalParams){
// summary: executes the specified function with the passed arguments
// example: dojo.publish(id/executeAction,[disableButton,startButton])
// functionName: function name to call and every following
// additionalParams: parameters will be pushed as parameter to the called function
if(this[functionName] && dojo.isFunction(this[functionName])){
var params = [];
dojo.forEach(arguments,function(el,i){
if(i!=0){
params.push(el);
}
});
epages.lang.hitch(this,functionName,params)();
}
},
destroyRendering: function() {
this.hide();
this.inherited("destroyRendering", arguments);
},
hide: function() {
this.inherited("hide", arguments);
if(epages.Browser.engine=="MSIE") { // layer display corrections
this.domNode.style.width="auto";
}
dojo.publish(this.id+'/hide',[{dialog: this}]);
},
show: function() {
this.inherited("show", arguments);
if(epages.Browser.engine=="MSIE") { // layer display corrections
this.domNode.style.width=this.domNode.offsetWidth+"px";
}
//set zIndex to epages.vars.ZIndex
if(this.domNode && epages.zIndex){
this.domNode.style.zIndex = epages.zIndex;
}
if(this._underlay){
this._underlay.domNode.style.zIndex = this.domNode.style.zIndex-1;
}
if(epages.zIndex){
epages.zIndex+=2;
}
//disconnect scrollevent from dialog, because there is no parameter in dojo dialog to achive this
for(var i = 0, iLength = this._modalconnects.length; i < iLength; i++){
var currentEventHandle = this._modalconnects[i];
if( currentEventHandle.length && currentEventHandle[1] && currentEventHandle[1] == 'onscroll'){
dojo.disconnect(currentEventHandle);
}
}
//check if there is enough space to see the close button
var popupTop = parseInt(this.domNode.style.top);
var popupLeft = parseInt(this.domNode.style.left);
if(popupTop < 0){
this.domNode.style.top = "0px";
}
if(popupLeft < 0){
this.domNode.style.left = "";
this.domNode.style.right = "0px";
}
else {
this.domNode.style.right = "";
}
//remove dragging
if(this._moveable){
this._moveable.destroy();
}
// manual focus handling : focus first input
if(!this.autofocus) {
var inputs = dojo.query('input', this.containerNode);
if(inputs && inputs.length > 0) {
inputs[0].focus();
}
}
// trigger resize to adjust CKEditor dimensions
jq(window).trigger('resize');
dojo.publish(this.id+'/show',[{dialog: this}]);
},
close: function() {
this.hide();
window.setTimeout(dojo.hitch(this,function(){
this._destroyContent();
this._destroyButtons();
}),this.duration);
},
setupContent: function(/*Object*/ opt) {
// summary: setup new content (destorys old content contentarea, tabs, buttons)
// opt: {
// content - string / domNode / widget object (strings may contain widgets e.g. <div dojoType="epages.widget.Tooltip"></div>)
// buttons - array with buttons e.g. [{label: 'Cancel',onclick: function() {this._modalDialogWidget.hide();}]}
// width - integer or string - width of content area
// height - integer or string - height of content area
// scroll - string - possible values: 'y', 'x', 'scroll', 'hidden'
// title - string - text in titlebar
// translationName - string (url) specify translation file to translate language tags in title attribute
// url - load content via url
// destroyWidgetOnClose - boolean - option to destroy widgets after closing the content widget (also after setting up new content)
// }
this._destroyTabs();
this._destroyContent();
this._destroyButtons();
if (opt.buttons){
this.setupButtons(opt.buttons);
}
this._createContent(opt);
this._createTabs();
},
setupButtons: function (buttons) {
this._destroyButtons();
this._createButtons(buttons);
},
setTitle: function(title) {
this.titleNode.innerHTML = title;
},
/**
* widget button/ display functions
*/
hideInnerButtonBar : function() {
this.innerButtonBarNode.style.display ='none';
},
showInnerButtonBar : function() {
this.innerButtonBarNode.style.display ='';
},
disableButton : function(/* string|DomNode*/ but) {
// summary: disables specified button
if(dojo.isString(but)){
var buttons = dojo.query("[buttonid="+but+"]", this.domNode );
if(buttons){
buttons = buttons[0];
}
} else {
var buttons = but;
}
if(buttons) {
dojo.removeClass(buttons, "Active");
dojo.addClass(buttons, "Disabled");
buttons.disabled=true;
}
dojo.forEach(this._events, function(evtmap) {
if(evtmap.button.domNode == buttons) {
dojo.disconnect(evtmap.event);
}
});
},
enableButton : function(/* string */ buttonId) {
// summary: enables specified button
var buttonData = undefined;
dojo.forEach(this.buttons, function (button) {
if(button.buttonId == buttonId) {
buttonData = button;
}
});
if(buttonData && buttonData.domNode.disabled == true) {
buttonData.domNode.disabled=false;
if(buttonData.cssClass) {
dojo.addClass(buttonData.domNode, buttonData.cssClass );
}
dojo.removeClass(buttonData.domNode, "Disabled");
dojo.forEach(this._events, function(evtmap) {
if(evtmap.button.buttonId == buttonId) {
evtmap.event = dojo.connect(buttonData.domNode, "onclick", buttonData, "onclick");
}
});
}
},
_createContent: function(/*Object*/ opt) {
if(opt){
dojo.mixin(this.options, opt);
}
var translation = undefined;
if(this.options.translationName) {
translation = new epages.io.Translation(this.options.translationName,"auto");
if(this.options.title){
this.options.title = translation.replaceLanguageTags(this.options.title);
}
}
if (this.options.title){
this.setTitle(this.options.title);
}
// set Layout
switch(this.options.scroll){
case "y":
this.containerNode.style.overflowY='scroll';
break;
case "x":
this.containerNode.style.overflowX='scroll';
break;
case "scroll":
this.containerNode.style.overflow='scroll';
break;
case "hidden":
this.containerNode.style.overflow='hidden';
break;
default:
this.containerNode.style.overflow='auto';
break;
}
if (this.options.width) {
if (typeof this.options.width == 'number') {
this.layerContentNode.style.width=this.options.width+"px";
} else {
this.layerContentNode.style.width=this.options.width;
}
} else {
this.containerNode.style.width="auto";
this.layerContentNode.style.width="auto";
}
if (this.options.height) {
if (typeof this.options.height == 'number') {
this.containerNode.style.height=this.options.height+"px";
} else {
this.containerNode.style.height=this.options.height;
}
} else {
this.containerNode.style.height="auto";
}
if (this.options.url != null) {
// url, use contentPane
if (this._contentPane == null) {
// contentPane does not exist -> create it
this._contentPane = new dojox.layout.ContentPane({
// url of content
href: this.options.url,
// wait for download to finish
preload: true,
// extract content from body tag
extractContent: false,
// adjust relative paths
adjustPaths: true,
// set content on download end to avoid resizing problem <-- does not work
ioMethod: function(args) {
var result = dojo.xhrGet(args);
if(translation){
result.addCallback(function(html){
return translation.replaceLanguageTags(html);
});
}
return result;
},
onLoad: dojo.hitch(this, function() {
//Timeout necessary for IE
window.setTimeout(dojo.hitch(this,function(){
this.containerNode.appendChild(this._contentPane.domNode);
// call event function
if (this.options && this.options.onLoad && typeof this.options.onLoad == 'function'){
this.options.onLoad();
}
this.layout();
this.show();
this._createTabs();
dojo.publish(this.id+'/onLoadContentPane',[{dialog: this}]);
}),10);
})
});
this._contentPane.refresh();
} else {
this._contentPane.setHref(this.options.url);
}
} else {
if(typeof this.options.content == "object") {
// content, string, nodes or widgets
if(this.options.content.domNode) { // widget
this.containerNode.appendChild(this.options.content.domNode);
this._contentWidget=this.options.content;
} else { // dom node
this.containerNode.appendChild(this.options.content);
}
} else if(typeof this.options.content == "string") {
this.containerNode.innerHTML=this.options.content; // html string
var scripts = this.containerNode.getElementsByTagName('script');
var win = this._doc.parentWindow ? this._doc.parentWindow : this._doc.defaultView;
for( var i=0,iLength=scripts.length ; i<iLength ; i++ ) {
if (scripts[i].childNodes.length > 0) {
// Mozilla
// Fix for bug https://bugzilla.mozilla.org/show_bug.cgi?id=194231: only 4K string in array element
var evalString = "";
for( var j=0,jLength=scripts[i].childNodes.length ; j<jLength ; j++ ) {
evalString += scripts[i].childNodes[j].nodeValue;
}
win.eval(evalString);
} else {
// IE
win.eval(scripts[i].innerHTML);
}
}
win.dojo.parser.parse(this.containerNode); // build widgets
//epages.widget.TransformButtons(this.containerNode);
}
}
dojo.publish(this.id+'/change',[{dialog: this}]);
},
_destroyContent: function() {
this.options.scroll=undefined;
this.options.width=undefined;
this.options.height=undefined;
this.options.title=undefined;
this.options.url=undefined;
if(this.titleNode.firstChild){
this.titleNode.firstChild.data=" ";
}
this.containerNode.style.overflow='auto';
this.containerNode.style.overflowX='auto';
this.containerNode.style.overflowY='auto';
this.containerNode.style.width="auto";
this.layerContentNode.style.width="auto";
this.containerNode.style.height="auto";
this.innerButtonBarNode.style.display="none";
this.tabBarNode.style.display="none";
// remove containerNode children
epages.html.removeChildren(this.containerNode);
if(typeof this.options.content == "object" && this.options.destroyWidgetOnClose){
this.options.content.destroy(); // destroy widget
}
this._contentWidget = null;
this.options.content = "";
},
_createButtons: function(/* Object[] */ buttons) {
// summary: create modal dialog buttons
// buttons:
// [{
// label: '{Delete}',
// cssClass: 'Active',
// buttonId: 'delete',
// hideOnShow: 'false',
// isDisabled: 'false',
// onclick: function() {
// me.deleteNavigationElement();
// this._modalDialogWidget.hide();
// }
// },{
// label: '{Cancel}',
// onclick: function() { this._modalDialogWidget.hide(); }
// }]
if(buttons.length){
this.innerButtonBarNode.style.display="";
}
this.buttons = [];
this._events = [];
dojo.forEach(buttons, function (button) {
button.domNode=[];
var tmplProcessor=new epages.Template({
template: this.buttonTemplateString,
vars : {
'Label': button.label,
'Class': button.cssClass ? button.cssClass : '',
'buttonId': (button.buttonId) ? 'buttonid='+button.buttonId+' ' : ''
}
});
var buttonNode= this.createNodesFromText(tmplProcessor.generateOutput());
this.innerButtonBarNode.appendChild(buttonNode);
button.domNode=buttonNode;
dojo.mixin(button, {_modalDialogWidget: this, _contentWidget: this._contentWidget});
this._events.push({ event: dojo.connect(button.domNode, "onclick", button, "onclick"), button : button});
this.buttons.push(button);
if(button.isDisabled == 'true'){
this.disableButton(buttonNode);
}
}, this);
this.clearFloatNode = document.createElement("div");
this.clearFloatNode.className="ClearBoth";
this.innerButtonBarNode.appendChild(this.clearFloatNode);
},
_destroyButtons: function () {
dojo.forEach(this._events, function(evtmap) {
dojo.disconnect(evtmap.event);
});
dojo.forEach(this.buttons, function (button) {
button.domNode.parentNode.removeChild(button.domNode);
button.domNode = undefined;
});
this._events = null;
delete this._events; // delete var
this.buttons=[];
if(this.clearFloatNode !== undefined && this.clearFloatNode.parentNode != null) {
this.clearFloatNode.parentNode.removeChild(this.clearFloatNode);
this.clearFloatNode = undefined;
}
},
_createTabs: function() {
// summary: creates tabs by looking for dom nodes with css class "TabPage"
// description: tab labels ar specified by attribute ep_label of the dom node
var tabs = epages.html.getElementsByClassName('TabPage',this.containerNode);
if(tabs.length && tabs.length > 1){
this.tabBarNode.style.display="";
dojo.addClass(this.tabBarNode, "Visible");
this._tabs = [];
this._tabEvents = [];
dojo.forEach(tabs, function (domNode) {
var tab = {
domNode : [],
changeNode: domNode
};
var tmplProcessor = new epages.Template({
template: this.tabTemplateString,
vars : {
'Label': domNode.getAttribute('ep_label')
}
});
var tabNode = this.createNodesFromText(tmplProcessor.generateOutput());
this.tabBarNode.appendChild(tabNode);
tab.domNode = tabNode;
//dojo.mixin(tab, {_modalDialogWidget: this, _contentWidget: this._contentWidget});
this._tabEvents.push(dojo.connect(tab.domNode, "onclick", this, "_onTabClick"));
tab.changeNode.style.display = 'none';
this._tabs.push(tab);
}, this);
//activate first tab
this._tabs[0].changeNode.style.display = '';
dojo.addClass(this._tabs[0].domNode, 'Active');
this._currentTab = this._tabs[0];
} else {
dojo.removeClass(this.tabBarNode, "Visible");
}
},
_destroyTabs: function () {
dojo.forEach(this._tabEvents, dojo.disconnect);
dojo.forEach(this._tabs, function (tab) {
tab.domNode.parentNode.removeChild(tab.domNode);
tab.domNode = undefined;
tab.changeNode = undefined;
});
this._tabs=[];
this._currentTab = undefined;
},
_onTabClick: function(evt){
var targetTab = evt.currentTarget;
var tab = undefined;
for( var i=0,iLength=this._tabs.length ; i<iLength ; i++ ){
if(targetTab == this._tabs[i].domNode){
tab = this._tabs[i];
}
}
if(tab){
if(this._currentTab){
dojo.removeClass(this._currentTab.domNode,'Active');
this._currentTab.changeNode.style.display = 'none';
}
tab.changeNode.style.display = '';
dojo.addClass(tab.domNode, 'Active');
this._currentTab = tab;
dojo.publish(this.id+"/tabChange",[tab.changeNode]);
}
}
}
);