/* Copyright (c) 2006-2007, ePages GmbH All Rights Reserved. epages.cartridges.de_epages.design.widget.Navigationelement $Revision: 1.74 $ */ dojo.provide("epages.cartridges.de_epages.design.widget.Navigationelement"); dojo.require("epages.lang.array"); dojo.require("epages.lang.hash"); dojo.require("epages.string"); dojo.require("epages.widget.LocalizedWidget"); dojo.require("epages.event"); dojo.require("dijit.Menu"); dojo.require('epages.io.json'); dojo.require('epages.cartridges.de_epages.presentation.dragdrop'); dojo.require("dijit._Container"); dojo.require("epages.event"); dojo.require('epages.html'); dojo.require('epages.html.element'); dojo.require('epages.cartridges.de_epages.design.mcecontent'); epages.cartridges.de_epages.design.widget.Navigation = { dndHandler : undefined, // epages.cartridges.de_epages.presentation.dragdrop - drag and dro handler createElement : function (/*String*/navElementId, /*String*/styleId, /*String*/navBarAlias, /*String*/url, /*String*/navElAlign, /*Boolean*/positioning) { // summary: // function to create a new widget // description: // load template snippet, initalizes and insert the widget // navElementId: // navigation element type id // styleId: // ObjectID of current style // navBarAlias: // alias of navbar e.g. "Right" // url: // request url (default is '?') // navElAlign: // alignment of new widget (default is 'left') // positioning: // show/hide alignNode of new widget (default is 'false') if (url === undefined){ url = '?'; } if (navElAlign === undefined){ navElAlign = 'left'; } if (navElAlign!== 'left') { navElAlign = 'right'; } var j = new epages.io.Json(); var output = j.loadSync(url, { ChangeAction: 'AddNavElement', ChangeObjectID: styleId, NavElementID: navElementId, NavBarAlias: navBarAlias, Alignment: navElAlign.charAt(0).toUpperCase() + navElAlign.slice(1), ViewAction: 'JSONNavBarElementSnippet', IsEditorNavElements: 1, IsEditorModeEnabled: 1 }); if(output.error){ if(output.error.data && output.error.data.Errors) { //highjack translations hl = epages.cartridges.de_epages.design.widget.Navigationelement.prototype.translate("ErrorCreateNewPageElement"); tb = epages.cartridges.de_epages.design.widget.Navigationelement.prototype.translate("CreateNewPageElement"); dojo.publish("uimessage/showErrors", [hl, tb, output.error.data.Errors]); } return false; } else if(output.data){ var navbar = epages.NavBars[output.data.navbarid][3]; var doc = navbar.ownerDocument; var e = doc.createElement("div"); e.innerHTML = output.data.snippet; e.id = 'Element' + output.data.id; epages.html.disableHrefsAndActions(e); epages.cartridges.de_epages.design.widget.Navigation.getNavBarDelete(doc).appendChild(e); var scriptTags = e.getElementsByTagName('script'); for(var i = 0, iLength = scriptTags.length; i < iLength; i++){ //eval is needed to execute script for navigation elements that use jquery //doc.defaultView is needed to change context of eval to the context of the iframe //by using plain eval or new Function the context for the script would be wrong doc.defaultView.eval(scriptTags[i].innerHTML); } var win = (doc.parentWindow) ? doc.parentWindow : doc.defaultView; var widgetClass = 'epages.cartridges.de_epages.design.widget.Navigationelement'; if(win.epages.vars.NavigationElementWidgetTypes) { if(win.epages.vars.NavigationElementWidgetTypes[navElementId]) { widgetClass = win.epages.vars.NavigationElementWidgetTypes[navElementId]; //catch widget type win.dojo["require"](widgetClass); } } widgetClass='win.'+widgetClass; var w = new(eval(widgetClass))({ elementId: e.id, objectId: output.data.id, navbar: 'Delete', isCustomizable: output.data.isCustomizable, position: output.data.position, alignment: navElAlign, doc : doc, positioning: positioning }); w.setNavBar(output.data.navbarid); return w; } }, getNavBarDelete: function( doc ){ var node = this.getNavBarDelete.node || ( this.getNavBarDelete.node = $('NavBarDelete',doc) ); if ( !node ) { node = this.getNavBarDelete.node = doc.createElement("div"); node.id = 'NavBarDelete'; node.style.display = 'none'; doc.getElementsByTagName("body")[0].appendChild(node); } return node; } }; dojo.declare( "epages.cartridges.de_epages.design.widget.Navigationelement", [epages.widget.LocalizedWidget,dijit._Container], { /** * public properties */ objectId : '', // String - epages objectid of navigation element position : '', // String - current position in navbar alignment : 'left', // String - 'left' or 'right' in navbar. left : 'auto', // String - pixel value or 'auto' for css property 'left'. top : 'auto', // String - pixel value or 'auto' for css property 'top'. positioning : false, // Boolean - indicates whether to show the alignment/positioning tool. navbar : '', // String - current navbar identifier orientation : '', // String - current navbar orientation e.g. UpDown elementId : '', // String - id of the navigationelement domnode storeRoot : epages.vars.StoreRoot, // [readonly] String - epages store root path undoWidgetId : 'undoWidget', // String - id of undo widget isCustomizable : '', // Boolean - indicates weather the navigation element has an edit dialog or not url : '?', // String - request url string languageId : epages.vars.Locale.languageId, // string - current language id emptyString : '', // String - will be displayed in empty customizable html areas doc : undefined, // document - navigation elements document reloadOnOrientationChange: false, // Boolean - indicates weather the html code of an navigation element needs to be reloaded after changing the navbar (some navigation elements use a different html code base for navigation bars with different orientations) nameOrAlias : "", // String - #NameOrAlias _widgetsA : [], // Array - list of navelement widgets for each navbar('s left part) (prototype Array) _widgetsARight : [], // Array - list of navelement widgets for each navbar's right part (prototype Array). Only for horizontal navbars! _htmlUndo : undefined, // epages.cartridges.de_epages.presentation.widget.Undobuttons - html undo object to register changes _inputs : undefined, // domnode[] - list of editor inputs in edit dialog (name starts with editor_) positionNode : undefined, // domnode - input field to enable undo for position alignmentNode : undefined, // domnode - input field to enable undo for alignment inside navbar leftNode : undefined, // domnode - input field to enable undo for setting css property 'left' topNode : undefined, // domnode - input field to enable undo for alignment setting css property 'top' navbarChangeNode : undefined, // domnode - input field to enable undo for navbar navElementNode : undefined, // domnode - node of the original navigation element _navElementNodeCache: undefined, // hash - caches elementnodes for different navelement views (UpDown/LeftRight) _deleteConfirmation : false, // [readonly] Boolean - flag that indicates weather the delete confirmation dialog will be shown or not (flag source: top.epages.vars.SessionUserDeleteConfirmation) /** * widget properties */ imagePath : epages.themeUrl('images'), // String - path to widget image folder templatePath : dojo.moduleUrl('epages.cartridges.de_epages.design.widget','templates/Navigationelement.html'), // String - path to widget template translationName : dojo.moduleUrl('epages.cartridges.de_epages.design.widget','templates/translation'), // String - path to widget translation loadNavBarElement : function (navElementId, styleId, navBarAlias, url) { // summary: get and insert navbar element snippet if (url === undefined){ url = '?'; } var j = new epages.io.Json(); var output = j.loadSync(url, { ObjectID: styleId, NavElementID: navElementId, NavBarAlias: navBarAlias, ViewAction: 'JSONNavBarElementSnippet', IsEditorNavElements: 1, IsEditorModeEnabled: 1 }); if(output.error){ return false; } else if(output.data){ var navbar = epages.NavBars[output.data.navbarid][3]; var doc = navbar.ownerDocument; var e = doc.createElement("div"); e.innerHTML = output.data.snippet; e.id = 'Element' + output.data.id; epages.html.disableHrefsAndActions(e); return e; } }, elementNode : function () { // summary: // returns the element domnode which will be moved via dnd // description: // the domnode that will be moved can be the widgets root dom // node or the parent node of the dom node (td-tag) return this.orientation == 'UpDown' ? this.domNode : this.domNode.parentNode; // dom node }, navbarNode : function () { // summary: // returns the container node for dnd elements return this.elementNode().parentNode; }, elementNodes: function () { // summary: // returns all draggable nodes in the current navigation bar return dojo.filter(this.navbarNode().childNodes, function (el) { // DomNode[] return el.nodeType == 1; }); }, siblingWidgets: function () { // summary: // returns all draggable navbar widgets in the current navigation bar // with *left* alignment if (this._widgetsA && this._widgetsA[this.navbar]) { return [].concat(this._widgetsA[this.navbar]); } return [] }, siblingWidgetsRight: function () { // summary: // returns all draggable navbar widgets in the current navigation bar // with *right* alignment if (this._widgetsARight && this._widgetsARight[this.navbar]) { return [].concat(this._widgetsARight[this.navbar]); } return [] }, currentIndex: function () { // summary: returns the navigation bar index of the element return $A(this._widgetsA[this.navbar]).find(this); // Integer }, existsPosition: function (/*integer*/ position, /*integer*/ navbarid, /*string*/ alignment) { // summary: check weather the specified position exits in specified navbar if (navbarid === undefined){ navbarid = this.navbar; } if (alignment === undefined){ alignment = this.alignment; } var a = $A(this['_widgetsA' + ((this.alignment === 'right') ? 'Right' : '')][navbarid]).grep(function (el) { return parseInt(el.positionNode.value) == position; // Boolean }); return a.length > 0; // Boolean }, postMixInProperties: function() { // summary: prepare defaults this.inherited("postMixInProperties", arguments); if(this.doc === undefined || this.doc == ''){ this.doc = document; } if (typeof this.isCustomizable == 'string') { this.isCustomizable = epages.string.toBoolean(this.isCustomizable); } else { this.isCustomizable = this.isCustomizable == 0 ? false : true; } this._inputs = []; this.emptyString = '- '+this.translate('ClickToChangeContent')+' -'; if(top.epages.vars.SessionUserDeleteConfirmation == 1){ this._deleteConfirmation = true; } }, postCreate : function() { // summary: // prepare navelement widget nodes / events / ... this.inherited("postCreate", arguments); this.positionNode = this.doc.createElement("input"); this.positionNode.type = 'hidden'; this.positionNode.name = this.objectId + ':Position'; this.positionNode.value = this.position; this.alignmentNode = this.doc.createElement("input"); this.alignmentNode.type = 'hidden'; this.alignmentNode.name = this.objectId + ':Alignment'; this.alignmentNode.value = this.alignment.charAt(0).toUpperCase() + this.alignment.slice(1); this.leftNode = this.doc.createElement("input"); this.leftNode.type = 'hidden'; this.leftNode.name = this.objectId + ':Left'; this.leftNode.value = this.left; this.topNode = this.doc.createElement("input"); this.topNode.type = 'hidden'; this.topNode.name = this.objectId + ':Top'; this.topNode.value = this.top; this.navbarChangeNode = this.doc.createElement("input"); this.navbarChangeNode.type = 'hidden'; this.navbarChangeNode.name = this.objectId + ':NavBar'; this.navbarChangeNode.value = this.navbar; // IE fix onchange event if (epages.Browser.engine == 'MSIE') { this.doc.getElementsByTagName('body')[0].appendChild(this.positionNode); this.doc.getElementsByTagName('body')[0].appendChild(this.navbarChangeNode); this.doc.getElementsByTagName('body')[0].appendChild(this.alignmentNode); this.doc.getElementsByTagName('body')[0].appendChild(this.leftNode); this.doc.getElementsByTagName('body')[0].appendChild(this.topNode); } epages.cartridges.de_epages.design.widget.Navigation.getNavBarDelete(this.doc); if (epages.NavBars !== undefined) { epages.NavBars['Delete'] = ['Delete', 'UpDown', 'Delete']; } if (!this.isCustomizable){ this.editNode.style.display = 'none'; } if (!this.positioning) { dojo.query(this.alignNode).orphan(); } // get undo object for add inputs if (this._htmlUndo === undefined) { var undoWidget = $$(this.undoWidgetId); if (undoWidget === undefined) { console.warn('undo widget not found in '+this.declaredClass +'. (undoWidgetId = ' + this.undoWidgetId + ')'); } else { this._htmlUndo = undoWidget.getUndoObject(); } } // move navelement in my widget var element = $(this.elementId,this.doc); if (element) { $E(this.replaceNode.parentNode).replaceChild(element,this.replaceNode); } else { console.warn("widget Navigationelement can't find element:" + this.elementId); } var child = element.firstChild; while(child != null && this.navElementNode === undefined) { if(child.nodeType==1) { this.navElementNode = child; } child=child.nextSibling; } if(this.navElementNode){ this._adjustGeomtry(this.navElementNode); } // initialize navbar if (this.alignment === 'right') { if (this._widgetsARight[this.navbar] === undefined){ this._widgetsARight[this.navbar] = []; } this._widgetsARight[this.navbar].push(this); } else { // standard = left alignment if (this._widgetsA[this.navbar] === undefined){ this._widgetsA[this.navbar] = []; } this._widgetsA[this.navbar].push(this); } if (this._htmlUndo) { this._htmlUndo.setDefaultValue(this.positionNode); this._htmlUndo.setDefaultValue(this.navbarChangeNode); this._htmlUndo.setDefaultValue(this.alignmentNode); this._htmlUndo.setDefaultValue(this.leftNode); this._htmlUndo.setDefaultValue(this.topNode); } // add global drag and drop handler if it isn't already added if(epages.cartridges.de_epages.design.widget.Navigationelement.dndHandler === undefined) { epages.cartridges.de_epages.design.widget.Navigationelement.dndHandler=$DND("NavElements", [], $('Content')); } var win = (this.doc.parentWindow) ? this.doc.parentWindow : this.doc.defaultView; var dndHandler = win.epages.cartridges.de_epages.design.widget.Navigationelement.dndHandler; // register widget as drag and drop element dndHandler.addElement({ clickNode: this.dndNode, moveNode: this.domNode, widget: this, onDropInList: function(opt) { this.widget.onDropInList(opt); }, onDrop: function () { this.widget._resetPosition(); }, forceSize: true }); // connect events this.connect(this.deleteNode, 'onclick', 'onclickDeleteNode'); if (this.isCustomizable){ this.connect(this.editNode, 'onclick', 'onclickEditNode'); } if (epages.NavBars !== undefined) { this.connect(this.navbarChangeNode, 'onchange', 'onchangeNavbarChangeNode'); this.orientation = epages.NavBars[this.navbar][1]; } // In advanced and quick design we reset // the *top* and *left* css attributes set by SF-Style.StyleSheet.css // and do the *top* and *left* positiong via javascript i.e. the style attribute. // This way we can easily update these values without having to regenerate the CSS. // see EPG-26482: Possibility to float page elements individually // reset top and left css var navbarelem = dojo.query('> [id^="Element"]> [class*="NavBarElement"]', this.contentNode)[0]; if(navbarelem){ dojo.style(navbarelem, 'left', 'auto'); dojo.style(navbarelem, 'top', 'auto'); } // init top and left css dojo.style(this.domNode, 'left', this.left === 'auto' ? null : this.left + 'px'); dojo.style(this.domNode, 'top', this.top === 'auto' ? null : this.top + 'px'); // prepare for orientation change (differnet views of some navelements) this.reloadOnOrientationChange = (this.navElementNode && this.navElementNode.className.match("ReloadOnOrientationChange")) ? true : false; this._navElementNodeCache = $H(); this._navElementNodeCache.set(this.orientation, this.navElementNode); this.connect(this.positionNode, 'onchange', 'onchangePositionNode'); this.connect(this.alignmentNode, 'onchange', 'onchangeAlignmentNode'); this.connect(this.leftNode, 'onchange', 'onchangeLeftNode'); this.connect(this.topNode, 'onchange', 'onchangeTopNode'); }, setNodePosition: function (position) { // summary: // set new position this.positionNode.value = position; if (this._htmlUndo){ this._htmlUndo.addInput(this.positionNode); } }, onchangeLeftNode : function (evt) { dojo.stopEvent(evt); this.left = this.leftNode.value; dojo.style(this.domNode, 'left', this.left === 'auto' ? null : this.left + 'px'); if (this._htmlUndo){ this._htmlUndo.addInput(this.leftNode); } }, onchangeTopNode : function (evt) { dojo.stopEvent(evt); this.top = this.topNode.value; dojo.style(this.domNode, 'top', this.top === 'auto' ? null : this.top + 'px'); if (this._htmlUndo){ this._htmlUndo.addInput(this.topNode); } }, onchangeAlignmentNode: function (evt) { // summary: // set new alignment // really, this is only ever called by the htmlundo widget. dojo.stopEvent(evt); this.setNavBar(this.navbar, true, this.orientation,this.alignmentNode.value.toLowerCase()); }, onchangePositionNode: function (evt) { // summary: // called when position node fired a change / adjusts _widgetsA // and dom node postion // tags: // callback dojo.stopEvent(evt); // remove current (changed) var position = parseInt(this.positionNode.value); var waArray = $A(this['_widgetsA' + ((this.alignment === 'right') ? 'Right' : '')][this.navbar]); var oldlength = waArray.length; waArray.remove(waArray.find(this)); // add changed on right place var wa = waArray.grep(function (el) { return parseInt(el.positionNode.value) <= position; }).concat(this, waArray.grep(function (el) { return parseInt(el.positionNode.value) > position; })); if (oldlength != wa.length){ console.warn('Widget Navigationelement list changed!! oldlength:' + oldlength +'!= new length:'+ wa.length); } this['_widgetsA' + ((this.alignment === 'right') ? 'Right' : '')][this.navbar] = wa; // correct dom nodes for( var i=0,l=wa.length ; i<l ; i++ ) { wa[i].navbarNode().appendChild(wa[i].elementNode()); // renumber classnames var className = wa[i].navElementNode.className; var className = className.replace(/NavBarElement\d*/,"NavBarElement"+i); wa[i].navElementNode.className = className; } this.adjustNewGhostEol(); }, onclickDeleteNode: function (evt) { // summary: // called when delete node was clicked / shows a delete confirmation dialog // tags: // callback dojo.stopEvent(evt); if(this._deleteConfirmation){ var me = this; epages.topDojo.publish("uimessage/show", [ this.translate('AcceptDeletePageElement'), "", 'Dialog', { titleBar: this.translate('DeletePageElement'), typeClass: 'Confirmation', buttons: [{ label: '{Delete}', cssClass: 'Active', onclick: function() { me.deleteNavigationElement(); this._modalDialogWidget.hide(); } },{ label: '{Cancel}', onclick: function() { this._modalDialogWidget.hide(); } }] } ]); } else { this.deleteNavigationElement(); } }, deleteNavigationElement: function(){ // summary: // move navigation element into delete navigation bar this.setNavBar('Delete', false); dojo.publish("Navigationelement/DeleteFinished", []); }, setNavBar: function (navbarid, pushOnEnd, orientation, alignment) { // summary: // move navigation element into specified navigation bar if (this.navbar == navbarid && this.alignment == alignment){ return; } if (alignment === undefined) { alignment = this.alignment; } if (pushOnEnd === undefined){ pushOnEnd = true; } if (epages.NavBars !== undefined) { orientation = epages.NavBars[navbarid][1]; } this._resetPosition(); // reload element view for different orient (if necessary) if(orientation !== this.orientation && this.reloadOnOrientationChange) { var el = this._navElementNodeCache.get(orientation); if(el === undefined) { el = this.loadNavBarElement(this.elementId, this.objectId, epages.NavBars[navbarid][2]); if(el !== false){ // chache element this._navElementNodeCache.set(orientation, el); }else{ console.warn('Could not load different view of navigation element'); } } // replace domnode this.navElementNode.parentNode.replaceChild(el, this.navElementNode); // assign new domnode to object property this.navElementNode = el; } var navbar = $('NavBar' + ((navbarid === 'Delete') ? navbarid : (navbarid + ((alignment === 'right') ? 'Right' : ''))), this.doc); if (navbar == null && alignment === 'right') { console.warn('Element NavBar' + navbarid + ' has no right part.'); navbar = $('NavBar' + navbarid, this.doc); if (navbar) {this.alignment=alignment;} } if (navbar == null) { console.error('Element NavBar' + navbarid + ' not found.'); return; } // add to new list if (this._widgetsA[navbarid] === undefined){ this._widgetsA[navbarid] = []; } if (this._widgetsARight[navbarid] === undefined){ this._widgetsARight[navbarid] = []; } var wa = this['_widgetsA' + ((alignment === 'right') ? 'Right' : '')][navbarid]; var position = parseInt(this.positionNode.value); var positionChanged = false; if (wa.length) { if (!pushOnEnd && this.existsPosition(position, navbarid, this.alignment)){ pushOnEnd = true; } if (pushOnEnd) { var i = wa.length; var last = wa[i - 1]; var lastPos = parseInt(last.positionNode.value); if (position <= lastPos) { position = lastPos + 10; positionChanged = true; } } } // change dom nodes if (this.orientation == orientation) { $E(navbar).appendChild(this.elementNode()); } else { if (orientation == 'LeftRight') { // move from div to tr (add td) var td = this.doc.createElement('td'); $E(navbar).appendChild(td); td.appendChild(this.elementNode()); } else { // move from tr to div (remove td) var td = this.elementNode(); $E(navbar).appendChild(this.domNode); td.parentNode.removeChild(td); } this.orientation = orientation; } if (positionChanged){ this.positionNode.value = position; } this.navbarChangeNode.value = navbarid; // remove from old list and add to new var waOld = this['_widgetsA' + ((this.alignment === 'right') ? 'Right' : '')][this.navbar]; waOld.splice($A(waOld).find(this), 1); wa.push(this); this.navbar = navbarid; if(!pushOnEnd) { // move to correct position (enables buttons also) epages.event.fire(this.positionNode,'change'); } // set html elements for undo if (this._htmlUndo) { if (positionChanged){ this._htmlUndo.addInput(this.positionNode); } this._htmlUndo.addInput(this.navbarChangeNode); if (this.alignment !== alignment) { this.alignment = alignment; this.alignmentNode.value = alignment.charAt(0).toUpperCase() + alignment.slice(1); this._htmlUndo.addInput(this.alignmentNode); } } dojo.publish('droplistNavBar'+this.navbar+'/change', []); if (this.alignment === "right") { dojo.publish('droplistNavBar'+this.navbar + 'Right' + '/change', []); } this.adjustNewGhostEol(); this.alignment = alignment; }, adjustNewGhostEol: function() { // summary: correct position of new ghost (always last domnode) var navbarNodes=$('NavBar' + ((this.navbar === 'Delete') ? this.navbar : (this.navbar + ((this.alignment === 'right') ? 'Right' : ''))), this.doc).childNodes; for(var el in navbarNodes){ if(navbarNodes[el] !== undefined && navbarNodes[el].className=="Ghost New"){ $('NavBar' + ((this.navbar === 'Delete') ? this.navbar : (this.navbar + ((this.alignment === 'right') ? 'Right' : ''))), this.doc).appendChild(navbarNodes[el]); } } }, onchangeNavbarChangeNode: function (evt) { // summary: // called when NavbarChangeNode (idicates an navifation bar change) // changed / adjusts elements navbar assignment and publish droplist // change messages // tags: // callback dojo.stopEvent(evt); this.setNavBar(this.navbarChangeNode.value, false); // publish change event to old and new droplists if(this.domNode.ep_droplistid) { dojo.publish('droplist'+this.domNode.ep_droplistid+'/change', []); } dojo.publish('droplistNavBar'+this.navbar + '/change', []); if (this.alignment === "right") { dojo.publish('droplistNavBar'+this.navbar + 'Right' + '/change', []); } this.domNode.ep_droplistid='NavBar'+this.navbar; }, onDropInList: function(/*Object*/options) { // summary: // called by droplist handler / adjust new positon of navigation alement // tags: // callback var newNavbarid = options.listObject.options.navbarid; var newAlignment = options.listObject.options.alignment; //var newNavbarid = options.listContainer.options.navbarid; var successor = options.insertBefore; var isNewNavbar = this.navbar !== newNavbarid; if(isNewNavbar || (this.alignment !== newAlignment)) { this.setNavBar(newNavbarid, isNewNavbar, undefined, newAlignment); // always push to end insert } var wa = this['_widgetsA' + ((newAlignment === 'right') ? 'Right' : '')][newNavbarid]; if(successor != null && successor.className!="Ghost New") { var successorFound=false; for(var w in wa) { if(wa[w].domNode === successor) { var posPredecessor = (wa[w-1]) ? parseInt(wa[w-1].positionNode.value) : 0; var posSuccessor = parseInt(wa[w].positionNode.value); var posSuperSuccessor = (wa[w+1]) ? wa[w+1] : parseInt(wa[w].positionNode.value) + 10; var posDistance = parseInt((posSuperSuccessor-posPredecessor) / 3); var newPosDropped = posPredecessor + posDistance; var newPosSuccessor = posPredecessor + 2 * posDistance; var successorPositonNode = wa[w].positionNode; successorPositonNode.value = newPosSuccessor; epages.event.fire(successorPositonNode, 'change'); this.positionNode.value = newPosDropped; epages.event.fire(this.positionNode, 'change'); if (this._htmlUndo) { this._htmlUndo.addInput(successorPositonNode); this._htmlUndo.addInput(this.positionNode); } successorFound=true; break; } } if(!successorFound) { console.warn("Navigationelement.onDropInList: successor dom node not found"); } } else if(!isNewNavbar) { // insert as last element var last = wa[wa.length - 1]; var lastPos = parseInt(last.positionNode.value); this.positionNode.value = lastPos + 10; epages.event.fire(this.positionNode, 'change'); if (this._htmlUndo){ this._htmlUndo.addInput(this.positionNode); } } // fire click event to select navbar epages.event.fire($('NavBar'+this.navbar,this.doc), 'click'); dojo.publish("Navigationelement/onDropInListFinished", []); }, onclickEditNode: function (evt) { // summary: // show dialog for customizable navigation elements // tags: // callback if (evt !== undefined){ dojo.stopEvent(evt); } if (this._editorWidget === undefined) { // create new dialog this.createEditDialog(); this.initEditDialog(); } else { // dialog is already up and running this.resetEditDialogInputValues(); } this.onbeforeShowDialog(); this._editorWidget.show(); }, createEditDialog: function() { // summary: // create edit dialog for customizable navigation elements // description: // load dialog data and instanciates diaolg within a modal dialog widget // tags: // protected // load dialog template dojo.require('epages.io.json'); var json = new epages.io.Json(); var result = json.loadSync(this.url, { 'ViewAction': 'JSONSnippet', 'TemplateAction': 'EditSnippet', 'TemplateLanguageID': this.languageId, 'ObjectID': this.objectId }); // create and setup dialog var _navigationElementWidget = this; // Create an undo stack for dialogs top.epages.html.UnDo.prototype.undoNavigationElementWidgetStack.push(_navigationElementWidget); top.dojo["require"]('epages.widget.Modaldialog'); var newDiv = top.document.createElement('div'); // dialog insert point top.document.getElementsByTagName('body')[0].appendChild(newDiv); var nameOrAlias = this.nameOrAlias != "" ? ": "+this.nameOrAlias : ""; this._editorWidget = new top.epages.widget.Modaldialog({ options:{ title : _navigationElementWidget.translate('EditNavElement')+nameOrAlias, content: result.data.snippet, scroll: 'hidden' }, buttons: [{ label: _navigationElementWidget.translate('Apply'), cssClass: "Active", onclick: function() { // apply function - fire change on hidden element node this._modalDialogWidget.hide(); _navigationElementWidget.applyEditorDialogInputValues(); dojo.publish("Navigationelement/EditFinished", []); } }, { label: _navigationElementWidget.translate('Cancel'), onclick: function() { //cancel action, just hide dialog this._modalDialogWidget.hide(); _navigationElementWidget.resetEditDialogInputValues(); } }] }, newDiv); }, initEditDialog: function() { // summary: // called after edit dialog was created // description: // registers all relevant input elements (inputs starting with "editor_" followed by ObjectID:Attributname:LanguageID e.g. editor_12345:MyAttribute:1) // tags: // protected var undo = $$(this.undoWidgetId).undoObject; var _this = this; var iterator = dojo.hitch(this, function (el) { // parse dialog inputs, build a copy in parent window and register them to undo widget if (el.name === undefined || !el.name.match(/^editor_/)){ return; // skip unnamed inputs and inputs wich do not start with "editor_" } var hid = el.parentNode.ownerDocument.createElement('input'); // create a hidden input element in main window hid.name =el.name.substr(7); // cut "editor_" away hid.type ='hidden'; hid.value = $E(el).get(); // e.g. <input type="hidden" name="12345:MyAttribute" value="MyValue" /> if(el.getAttribute("ep_noundo")=="1") { hid.setAttribute("ep_noundo","1"); } var ep_publishmessage = el.getAttribute("ep_publishmessage"); el.parentNode.appendChild(hid); _this._inputs.push({ // save nodes to this._inputs array 'editorNode' : el, // editor node (edit node in dialog) -> format example: <inupt type="hidden" name="editor_1234:Logo:1" value="myvalue" /> 'hiddenNode' : hid, // hidden input node (real value container for undo widget) -> <input type="hidden" name="1234:Logo::1" value="myvalue" /> 'ep_publishmessage' : ep_publishmessage // pass input message identifier }); undo.registerInput(hid); // register the hidden input node to undo widget epages.topDojo.connect(hid, 'onchange', _this, 'setPreview'); // connect inputs to preview function }); // make copy because getElementsByTagName will be change during the iterator var aCopy = []; dojo.forEach(this._editorWidget.domNode.getElementsByTagName("input"), function (el) { aCopy.push(el); }); dojo.forEach(aCopy, iterator); dojo.forEach(this._editorWidget.domNode.getElementsByTagName("select"), iterator); dojo.forEach(this._editorWidget.domNode.getElementsByTagName("textarea"), iterator); }, onbeforeShowDialog: function() { // summary: // override function - called before dialog widget is shown // tags: callback extension protected }, applyEditorDialogInputValues : function() { // summary: // apply editor inputs (this._inputs) to hidden inputs (data storage) var _this = this; // set timeout because CKE needs some time to write back WYSIWYG data window.setTimeout(function(){ dojo.forEach(_this._inputs, function (el) { var value = $E(el.editorNode).get(); if(el.editorNode.type=='radio' || el.editorNode.type=='checkbox'){ // special handling for radio buttons if(el.editorNode.checked == true){ el.hiddenNode.value = value; _this.onbeforePreview(el.hiddenNode); epages.event.fire(el.hiddenNode,'change'); }else{ var topLength = top.document.getElementsByName(el.hiddenNode.name).length; var selfLength = document.getElementsByName(el.hiddenNode.name).length; if(((topLength!==undefined)&&(topLength>1)) || ((selfLength!==undefined)&&(selfLength>1))){ el.hiddenNode.value = ""; } } } else if (el.hiddenNode.value != value) { // fire only if value is different el.hiddenNode.value = value; _this.onbeforePreview(el.hiddenNode); epages.event.fire(el.hiddenNode,'change'); } }, _this); }, 300); }, resetEditDialogInputValues: function() { // summary: // reset input values / set values from hiddenNode // (data storage to editor inputs (this._inputs) // tags: // protected dojo.forEach(this._inputs, function (el) { var formElement = $E(el.editorNode); var elValue = formElement.get(); var hiddenValue = el.hiddenNode.value; if(elValue != hiddenValue) { // set value only if changed formElement.set(hiddenValue); formElement.callOnChange(); } }); }, onbeforePreview: function(/*domnode*/ inputNode) { // summary: // called before setPreview (change is fired on input node) - // publishes a message on all input that have specified a message // identifier (ep_publishmessage) // description: // You may override this function but don't forget to call // this.inherited("onbeforePreview", arguments); // inputNode: // input node that has changed in dialog // tags: // callback protected extension if(inputNode['ep_publishmessage']) { // publish input specific message before change is fired, pass input node dojo.publish(inputNode['ep_publishmessage']+'/beforeChangeFired', [inputNode]); } }, setPreview: function(evt) { // summary: // update navigation element preview (called onchange: input node) // description: // Update content (texts / file url) of displayed naviagtion elements. // format example preview nodes: <img id="eid_1234:Logo:1" src="myurl" /> // tags: // callback protected var el = evt.target; // get input node (changed content) var node = $('eid_' + el.name, this.domNode.ownerDocument); // get target node if (node) { var value = el.value == '' ? this.emptyString : el.value; // get value; if(node.nodeName.match(/input|textarea|select/i)) { // set value to form fields node.value = value; } else if(node.nodeName.match(/img/i)) { // set value to image node.src=el.value; } else { // set value as html content node.innerHTML = el.value == '' ? this.emptyString : el.value; node.innerHTML = epages.cartridges.de_epages.design.MceContent.prototype.string2Preview(node.innerHTML); epages.html.disableHrefsAndActions(node); this._adjustGeomtry(node); } jQuery('body').trigger('updatepreview'); } else { // no updates console.warn("node '%s' not found, possible not in template ("+this.declaredClass+")", 'eid_' + el.name); } }, _adjustGeomtry: function(node) { // summary: // adjust gemoetry of the original navigation element / force minimal size // tags: // protected dojo.removeClass(node, "ForceMinSize"); var cn = node.className; if((node.clientWidth < 11 && node.offsetWidth < 11 || node.clientHeight < 11 && node.offsetHeight < 11) && cn.match("NavigationText")){ dojo.addClass(node, "ForceMinSize"); } }, _resetPosition: function() { // summary: // reset *top* and *left* values to "auto", if necessary. // tags: // protected if (this.left !== 'auto') { this.leftNode.value = 'auto'; epages.event.fire(this.leftNode, 'change'); } if (this.top !== 'auto') { this.topNode.value = 'auto'; epages.event.fire(this.topNode, 'change'); } }, // dojoAttachEvent mouseenter_ButtonAndMetainfo: function() { // summary: // show ButtonAndMetaInfo layer // tags: // callback protected var el= this.elementNode(); if(el && !epages.cartridges.de_epages.design.widget.Navigation.dndHandler) { dojo.addClass(el, "SetOver"); } }, mouseleave_ButtonAndMetainfo: function(evt) { // summary: // hide ButtonAndMetaInfo layer // tags: // callback protected var el_t = evt.target; var el_c = evt.currentTarget; var el= this.elementNode(); if(el && el_t === el_c){ dojo.removeClass(this.elementNode(), "SetOver"); } } } );