/* js/tabpane.js */
// This function is used to define if the browser supports the needed
// features
function hasSupport() {
if (typeof hasSupport.support != "undefined")
return hasSupport.support;
var ie5 = /msie 5\.[0-9]/i.test( navigator.userAgent );
hasSupport.support = ( typeof document.implementation != "undefined" &&
document.implementation.hasFeature( "html", "1.0" ) || ie5 )
/* Original code			
// IE5 has a serious DOM1 bug... Patch it!
if ( ie5 ) {
document._getElementsByTagName = document.getElementsByTagName;
document.getElementsByTagName = function ( sTagName ) {
if ( sTagName == "*" )
return document.all;
else
return document._getElementsByTagName( sTagName );
};
}
*/
/* Patch for the bug with IE55 and NT4
if ( ie55 ) {
document._getElementsByTagName = document.getElementsByTagName;
document.getElementsByTagName = function ( sTagName ) {
if ( sTagName == "*" )
return document.all;
else
return document._getElementsByTagName( sTagName );
};
}
*/
// will cause bug when ie55 patched, so rewrite above
if ( ie5 ) {  
document._getAllElements = function () {
return document.all;
}
} else {
document._getAllElements = function () {
return document.getElementsByTagName("*");
}   
}
return hasSupport.support;
}
var groups = new Array() ;
var ieMac = navigator.appVersion.indexOf("MSIE") >= 0 && navigator.appVersion.indexOf("Mac") >= 0 ;
///////////////////////////////////////////////////////////////////////////////////
// The constructor for tab panes
//
// el : HTMLElement		The html element used to represent the tab pane
// bUseCookie : Boolean	Optional. Default is true. Used to determine whether to us
//						persistance using cookies or not
//
function WebFXTabPane( el, bUseCookie ) {
if ( !hasSupport() || el == null ) return;
this.element = el;
this.element.tabPane = this;
var cn = this.element.className ;
this.group = cn.length>8 ? cn.substring(9,cn.length) : null;
if (this.group) {
if (!groups[this.group]) groups[this.group] = new Array() ;
groups[this.group][groups[this.group].length]=this.element.id ;
}
this.pages = [];
this.selectedIndex = null;
this.useCookie = false; // :OD:NOTE: bug-jcms-4.0-148 (Form with many tabs may logout the user).  bUseCookie != null ? bUseCookie : true;
// add class name tag to class name
this.element.className = this.classNameTag + " " + this.element.className;
// add tab row
this.tabRow = document.createElement( "div" );
this.tabRow.className = "tab-row";
if (ieMac) this.tabRow.style.height = "1px";
el.insertBefore( this.tabRow, el.firstChild );
var tabIndex = 0;
//	if ( this.useCookie ) { // :OD:NOTE: bug-jcms-4.0-148 vs. force tab to open (setSelectedTab())
tabIndex = Number( WebFXTabPane.getCookie( "webfxtab_" + this.element.id ) );
if ( isNaN( tabIndex ))
tabIndex = 0;
//	}
this.selectedIndex = tabIndex;
// loop through child nodes and add them
var n;
var cs = el.childNodes;
for (var i = 0; i < cs.length; i++) {
if (cs[i].nodeType == 1 && cs[i].className == "tab-page") {
this.addTabPage( cs[i] );
}
}
if (this.selectedIndex >= this.pages.length)
this.setSelectedIndex(0);
}
WebFXTabPane.prototype.classNameTag = "dynamic-tab-pane-control";
WebFXTabPane.prototype.setSelectedIndex = function ( n ) {
if (n > this.pages.length)
n = 0;
if (this.selectedIndex != n) {
if (this.selectedIndex != null && this.pages[ this.selectedIndex ] != null )
this.pages[ this.selectedIndex ].hide();
this.selectedIndex = n;
this.pages[ this.selectedIndex ].show();
if ( this.useCookie )
WebFXTabPane.setCookie( "webfxtab_" + this.element.id, n );	// session cookie
}
};
WebFXTabPane.prototype.getSelectedIndex = function () {
return this.selectedIndex;
};
WebFXTabPane.prototype.addTabPage = function ( oElement ) {
if ( !hasSupport() ) return;
if ( oElement.tabPage == this )	// already added
return oElement.tabPage;
var n = this.pages.length;
var tp = this.pages[n] = new WebFXTabPage( oElement, this, n );
tp.tabPane = this;
// move the tab out of the box
this.tabRow.appendChild( tp.tab );
if ( n == this.selectedIndex )
tp.show();
else
tp.hide();
return tp;
};
WebFXTabPane.prototype.dispose = function () {
this.element.tabPane = null;
this.element = null;		
this.tabRow = null;
for (var i = 0; i < this.pages.length; i++) {
this.pages[i].dispose();
this.pages[i] = null;
}
this.pages = null;
};
// Cookie handling
WebFXTabPane.setCookie = function ( sName, sValue, nDays ) {
var expires = "";
if ( nDays ) {
var d = new Date();
d.setTime( d.getTime() + nDays * 24 * 60 * 60 * 1000 );
expires = "; expires=" + d.toGMTString();
}
document.cookie = sName + "=" + sValue + expires + "; path=/";
};
WebFXTabPane.getCookie = function (sName) {
var re = new RegExp( "(\;|^)[^;]*(" + sName + ")\=([^;]*)(;|$)" );
var res = re.exec( document.cookie );
return res != null ? res[3] : null;
};
WebFXTabPane.removeCookie = function ( name ) {
setCookie( name, "", -1 );
};
///////////////////////////////////////////////////////////////////////////////////
// The constructor for tab pages. This one should not be used.
// Use WebFXTabPage.addTabPage instead
//
// el : HTMLElement			The html element used to represent the tab pane
// tabPane : WebFXTabPane	The parent tab pane
// nindex :	Number			The index of the page in the parent pane page array
//
function WebFXTabPage( el, tabPane, nIndex ) {
if ( !hasSupport() || el == null ) return;
this.element = el;
this.element.tabPage = this;
this.index = nIndex;
this.group = tabPane.group ;
var cs = el.childNodes;
for (var i = 0; i < cs.length; i++) {
if (cs[i].nodeType == 1 && cs[i].className == "tab") {
this.tab = cs[i];
break;
}
}
// insert a tag around content to support keyboard navigation	
var a = document.createElement( "A" );
this.aElement = a;
a.href = "#";
a.onclick = function () { return false; };
a.hideFocus = true ;
while ( this.tab.hasChildNodes() )
a.appendChild( this.tab.firstChild );
this.tab.appendChild( a );
// hook up events, using DOM0
var oThis = this;
this.tab.onclick = function () { oThis.select(oThis.group); };
/* 
JALIOS: Commented to reduce jumper tab
this.tab.onmouseover = function () { WebFXTabPage.tabOver( oThis ); };
this.tab.onmouseout = function () { WebFXTabPage.tabOut( oThis ); }; 
*/
}
WebFXTabPage.prototype.show = function () {
var el = this.tab;
el.className = "tab_selected";
this.element.style.display = "block";
};
WebFXTabPage.prototype.hide = function () {
var el = this.tab;
el.className = "tab";
this.element.style.display = "none";
};
WebFXTabPage.prototype.select = function (group) {
if (group) {
var g=groups[group];
for(var i=0 ; i<g.length ; i++) {
var el = document.getElementById(g[i]) ;
if (el) {
if (this.index<el.tabPane.pages.length)
el.tabPane.setSelectedIndex( this.index ) ;
}
}
}
else this.tabPane.setSelectedIndex( this.index );
};
WebFXTabPage.prototype.dispose = function () {
this.aElement.onclick = null;
this.aElement = null;
this.element.tabPage = null;
this.tab.onclick = null;
this.tab.onmouseover = null;
this.tab.onmouseout = null;
this.tab = null;
this.tabPane = null;
this.element = null;
};
WebFXTabPage.tabOver = function ( tabpage ) {
var el = tabpage.tab;
var s = el.className + " hover";
s = s.replace(/ +/g, " ");
el.className = s;
};
WebFXTabPage.tabOut = function ( tabpage ) {
var el = tabpage.tab;
var s = el.className;
s = s.replace(/ hover/g, "");
el.className = s;
};
// This function initializes all uninitialized tab panes and tab pages
function setupAllTabs() {
if ( !hasSupport() ) return;
if ( document.TabPaneSetupAllTabsDone ) { return; }
document.TabPaneSetupAllTabsDone = true;
//var all = document.getElementsByTagName( "*" );
// will cause bug when ie55 patched , so rewrite above
var all = document._getAllElements();
var l = all.length;
var tabPaneRe = /tab\-pane/;
var tabPageRe = /tab\-page/;
var cn, el;
var parentTabPane;
for ( var i = 0; i < l; i++ ) {
el = all[i]
cn = el.className;
// no className
if ( cn == "" ) continue;
// uninitiated tab pane
if ( tabPaneRe.test( cn ) && !el.tabPane )
new WebFXTabPane( el );
// unitiated tab page wit a valid tab pane parent
else if ( tabPageRe.test( cn ) && !el.tabPage &&
tabPaneRe.test( el.parentNode.className ) ) {
el.parentNode.tabPane.addTabPage( el );			
}
}
if (document.TabPaneLanguageTab) {
setSelectedLanguageTab(document.TabPaneLanguageTab);
}
}
function disposeAllTabs() {
if ( !hasSupport() ) return;
//var all = document.getElementsByTagName( "*" );
// will cause bug when ie55 patched , so rewrite above
var all = document._getAllElements();
var l = all.length;
var tabPaneRe = /tab\-pane/;
var cn, el;
var tabPanes = [];
for ( var i = 0; i < l; i++ ) {
el = all[i]
cn = el.className;
// no className
if ( cn == "" ) continue;
// tab pane
if ( tabPaneRe.test( cn ) && el.tabPane )
tabPanes[tabPanes.length] = el.tabPane;
}
for (var i = tabPanes.length - 1; i >= 0; i--) {
tabPanes[i].dispose();
tabPanes[i] = null;
}
}
function setSelectedTab(tabPaneId, index) {
document.cookie = "webfxtab_" + tabPaneId + "=" + index + "; path=/";
}
function setSelectedLanguageTab(langIndex) {
// Defer to setupAllTabs if tabpane has no yet been initialized
if ( !document.TabPaneSetupAllTabsDone ) {
document.TabPaneLanguageTab = langIndex;
return;
}
var g = groups["lang"];
if (g == null || g == "undefined") {
return;
}
for(var i=0 ; i<g.length ; i++) {
var el = document.getElementById(g[i]) ;
if (el) {
if (langIndex < el.tabPane.pages.length)
el.tabPane.setSelectedIndex( langIndex ) ;
}
}
}
/* js/tree.js */
function toggleUL(event, ulId,img,open,openable) {
ulElt = document.getElementById(ulId) ;
ulElt.style.display = ulElt.style.display=="none" ? "block" : "none" ;
img.src = ulElt.style.display=="block" ? open : openable ;
if ( (event&&event.ctrlKey) ) {
var descendants = ulElt.getElementsByTagName("UL") ;
var icons = ulElt.getElementsByTagName("IMG") ;
if (ulElt.style.display=="block") {
for(var i=0;i<descendants.length;i++) { descendants[i].style.display = "block" ; }
for(var i=0;i<icons.length;i++) { if (icons[i].src.indexOf(openable)!=-1) { icons[i].src = open ; } }
} else {
for(var i=0;i<descendants.length;i++) { descendants[i].style.display = "none" ; }
for(var i=0;i<icons.length;i++) { if (icons[i].src.indexOf(open)!=-1) { icons[i].src = openable ; } }  
}
}
}
/* js/treegroup.js */
//
// treegroup.js - $Revision: 1.4 $ - since jcms-5.6
// This file is used by the navigation tree group (see Group.printTreeGroup())
//
var TreeGroup = {
/**
* Open/close a workspace node.
*
* @param title the title div
* @param tree the tree div
* @since jcms-5.6.0
*/
toggle: function (title, tree) {
title = $(title);
// Toggle tree div
tree.toggle();
// Change title div class
if (tree.style.display == "") {
title.addClassName("open");
} else {
title.removeClassName("open");
}
},
init: function() {
// Iterate over all the img tag in the tree
$$(".tree img").each(function(img) {
// Add the toggle behaviour for each node
Event.observe(img, 'click' , function() { 
// For each node under this <li>
var li = img.parentNode;
$A(li.childNodes).each(function(subNode){
// Just consider <ul> tag
if (subNode.tagName != "UL") {
return;
}
// Toggle the UL
subNode.toggle();
// Change icon
if (subNode.style.display == "") {
img.src = "images/jalios/icons/groupParentOpened.gif";
} else {
img.src = "images/jalios/icons/groupParent.gif";
}
});
});
});
}
}
/* js/widget.js */
// -----------------------------------------------------------------------------
//  INITIALISATION
// -----------------------------------------------------------------------------
Event.observe(window, 'load' , function() { setTimeout(function(){ setupSingleSubmitButton();} ,1); });
function initUnloadMessage(){
var func = function(event){
if(event.keyCode == 116){  return; } // Skip F5 key
window.onbeforeunload = function unloadMess() { return I18N.glp('warn.edit.contentlost'); } // Register unload message
Event.stopObserving(document, 'keypress' , func); // Unregister keypress listener
}
Event.observe(document, 'keypress' , func);
}
// ----------------------------------------------------------------------------
// Data Chooser 
// -----------------------------------------------------------------------------
function openDataChooser(window, ctxPath, form, widget, pos, jspPath, width, height){ // ctxPath must not end with '/', and jspPath must start with '/'
var formName   = getFormName(window.document, form);
var widgetPos  = getFormElementPos(form,widget)+pos;
var chooser    = ctxPath+jspPath+"targetInput=document."+formName+".elements["+widgetPos+"].value&targetLabel=document."+formName+".elements["+(widgetPos-1)+"].value";
popupWindow(chooser, 'DataChooser', width, height,'no','yes','yes',false);
}
// -----------------------------------------------------------------------------
// Date Chooser 
// -----------------------------------------------------------------------------
function openDateChooser(window, ctxPath, form, widget, pos, dateOnly, showWeek){ 
var formName   = getFormName(window.document, form);
var widgetPos   = getFormElementPos(form,widget)+pos;
var fieldValue  = escape(form.elements[widgetPos].value);
var targetInput = "document."+formName+".elements["+widgetPos+"].value";
var chooser     = ctxPath+"/work/calendarPopup.jsp?showWeekNbr="+showWeek+"&dateOnly="+dateOnly+"&datetime="+fieldValue+"&targetInput="+targetInput;
popupWindow(chooser, 'calendar', '300', dateOnly ? '260' : '275');
}
// -----------------------------------------------------------------------------
// Doc Chooser 
// -----------------------------------------------------------------------------
function openDocChooser(window, ctxPath, form, widget, pos, nbElt, id){ 
var formName   = getFormName(window.document, form);
var widgetPos  = getFormElementPos(form,widget) + pos;
var chooser    = ctxPath+"/work/docChooser.jsp?form="+formName+"&nbElt="+nbElt+"&startElt="+(widgetPos-1);
if (id){
chooser   = chooser+"&id="+id;
}
popupWindow(chooser, 'DocChooser', 640, 560,'no','yes','yes',false);
}
// -----------------------------------------------------------------------------
// File Chooser 
// -----------------------------------------------------------------------------
function openFileChooser(window, ctxPath, path, form, widget, pos){ 
var formName   = getFormName(window.document, form);
var widgetPos  = getFormElementPos(form,widget)+pos;
var chooser    = ctxPath+"/work/fileChooser.jsp?"+path+"targetInput="+formName+".elements["+widgetPos+"]&targetInputValue="+escape(form.elements[widgetPos].value);
popupWindow(chooser, 'FileChooser', 700, 500,'no','yes','yes',false);
}
// -----------------------------------------------------------------------------
// Color Chooser 
// -----------------------------------------------------------------------------
function openColorChooser(window, ctxPath, form, widget, pos){ 
var formName   = getFormName(window.document, form);
var widgetPos  = getFormElementPos(form,widget)+pos;
var chooser    = ctxPath+"/work/colorChooser.jsp?targetInput="+formName+".elements["+widgetPos+"]";
popupWindow(chooser, 'ColorChooser', 235, 220,'no','no','yes',false);
}
// -----------------------------------------------------------------------------
// Query Chooser 
// -----------------------------------------------------------------------------
function openQueryChooser(window, ctxPath, form, widget, pos){ 
var formName   = getFormName(window.document, form);
var widgetPos  = getFormElementPos(form,widget)+pos;
var chooser    = ctxPath+"/work/queryChooser.jsp?targetInput=document."+formName+".elements["+widgetPos+"].value&targetLabel=document."+formName+".elements["+(widgetPos-1)+"].value&qs="+escape(form.elements[widgetPos].value);
popupWindow(chooser, 'QueryChooser', 800, 400,'no','yes','yes',false);
}
// -----------------------------------------------------------------------------
// Image Chooser
// -----------------------------------------------------------------------------
function openImageChooser(window, ctxPath, form, widget, pos){ 
internalOpenImageChooser(window, ctxPath, form, widget, pos, false);
}
function openImagePubChooser(window, ctxPath, form, widget, pos){ 
internalOpenImageChooser(window, ctxPath, form, widget, pos, true);
}
function internalOpenImageChooser(window, ctxPath, form, widget, pos, isPubChooser){ 
var formName   = getFormName(window.document, form);
var widgetPos  = getFormElementPos(form,widget)+pos;
var chooser    = ctxPath + "/work/mediaBrowser.jsp?medias=image&jsFunc="
+ (isPubChooser ? "MediaBrowser.insertPub" : "MediaBrowser.insertMedia")
+ "&targetInput=document."+formName+".elements["+widgetPos+"]"
+ (isPubChooser ? ("&targetLabel=document."+formName+".elements["+(widgetPos-1)+"]") : "");
popupWindow(chooser, 'MediaBrowser', 930, 570,'no','no','no',false);
}
// -----------------------------------------------------------------------------
// Media Chooser 
// -----------------------------------------------------------------------------
function openMediaChooser(window, ctxPath, form, widget, pos){ 
internalOpenMediaChooser(window, ctxPath, form, widget, pos, 'MediaBrowser.insertMedia');
}
function openMediaPubChooser(window, ctxPath, form, widget, pos){ 
internalOpenMediaChooser(window, ctxPath, form, widget, pos, 'MediaBrowser.insertPub', true);
}
function internalOpenMediaChooser(window, ctxPath, form, widget, pos, jsfunc, label){ 
var formName   = getFormName(window.document, form);
var widgetPos  = getFormElementPos(form,widget)+pos;
var chooser    = ctxPath + "/work/mediaBrowser.jsp?media=all&jsFunc="+jsfunc
+ "&targetInput=document."+formName+".elements["+widgetPos+"]"
+ (label ? ("&targetLabel=document."+formName+".elements["+(widgetPos-1)+"]") : "");
popupWindow(chooser, 'MediaBrowser', 930, 570,'no','no','no',false);
}
// -----------------------------------------------------------------------------
// TEST SQLQuery
// -----------------------------------------------------------------------------
function testSQLQuery(window, ctxPath, form, widget, pos, title){
var sqlQuery   = form.elements[getFormElementPos(form,widget)+pos];
var dataSource = form.elements[getFormElementPos(form,widget+"DataSource")+pos];
var maxRows    = form.elements[getFormElementPos(form,widget+"MaxRows")+pos];
var chooser    = ctxPath+"/work/checkSQLQuery.jsp?";
chooser   += "dataSource=" +escape(dataSource.value);
chooser   += "&maxRows="   +escape(maxRows.value);
chooser   += "&sqlQuery="  +escape(sqlQuery.value);
// alert("pos: "+pos+"\ndataSource "+dataSource.value + "\nmaxRows " + maxRows.value + "\nsqlQuery "+sqlQuery.value);
popupWindow(chooser, title, 400, 600,'no','yes','yes',false);   
}
// -----------------------------------------------------------------------------
// Common jsFunc callback functions : Image and Media Chooser 
// -----------------------------------------------------------------------------
if (!window.MediaBrowser) {
var MediaBrowser = new Object();
}
Object.extend(MediaBrowser,{
/**
* @param fdId id of the FileDocument being inserted
* @param fdTitle title of the FileDocument being inserted
* @param fdMediaType media type of the FileDocument being inserted
*        ('image', 'video', 'audio', 'flash', 'other')
* @param fdUrl the relative url of the FileDocument being inserted
* @param targetInput the input in which to store the id or URL,
*        for example 'document.myForm.elements[12]'
* @param targetLabel the input in which to store the title
*        for example 'document.myForm.elements[13]'
*/
insertPub: function(fdId, fdTitle, fdMediaType, fdUrl, targetInput, targetLabel) {
var evalScript = targetInput + ".value = '" + fdId + "';";
evalScript += targetLabel + ".value = '" + fdTitle + "';";
eval(evalScript);
},
insertMedia: function(fdId, fdTitle, fdMediaType, fdUrl, targetInput, targetLabel) {
var evalScript = targetInput + ".value = '" + fdUrl + "';";
eval(evalScript);
}
});
// -----------------------------------------------------------------------------
// Duration Chooser 
// -----------------------------------------------------------------------------
function fillDurationField(window, form, widget, pos, resolution){
var widgetPos  = getFormElementPos(form,widget)+pos;
restrictToNumerics(form.elements[widgetPos+1]);
form.elements[widgetPos].value = form.elements[widgetPos+1].value * form.elements[widgetPos+2].value / resolution;
}
// ---------------------------------------
// Wysiwyg
// ---------------------------------------
// All processed done here are made to make sure that we do not allow
// form submit when content is not yet ready (which could submit partial on empty data).
var wysisygEditorToBeInitializedOnPage = 0;
/**
* Count the number of editors on the page, used by call back
*/
function countWysisygEditorOnPage() {
wysisygEditorToBeInitializedOnPage += $$('TEXTAREA.formRichText').size();
checkWysiwygEditorInitialization();
}
Event.observe(window, 'load', countWysisygEditorOnPage);
/**
* Callback method to use when one editor has been initialized properly.
*/
function wysiwygEditorInitialized() {
wysisygEditorToBeInitializedOnPage = wysisygEditorToBeInitializedOnPage - 1;
checkWysiwygEditorInitialization();
} 
/**
* This method should be called to check if all wysiwyg editors are completely ready.
*/
function checkWysiwygEditorInitialization() {
//alert('wysisygEditorToBeInitializedOnPage : ' + wysisygEditorToBeInitializedOnPage);
if (wysisygEditorToBeInitializedOnPage != 0) {
return;
}
if (window.document.editForm && window.document.editForm.pageLoaded) {
window.document.editForm.pageLoaded.value = 'true';
//alert('pageLoaded : ' + window.document.editForm.pageLoaded.value);
}
}
// -----------------------------------------------------------------------------
// Fields 
// -----------------------------------------------------------------------------
function fillOpenerField(window, form, widget, pos, id, label){
var widgetPos  = getFormElementPos(form,widget)+pos;
form.elements[widgetPos].value   = id;
form.elements[widgetPos-1].value = label;
window.close();
}
function submitAddCount(window, form, widget, fullwidget, addCount, langCount, id){
var elmCount = getFormElementCount(form, widget, id) / langCount;
fullwidget.value = elmCount+addCount;
simpleSubmitForm(window, form, "opRefresh", "Wait WYSIWYG");
}
function clearDefField(def, e1, e2, e3, e4) {
if (e1 != null) {
if (e1.options)
e1.options[0].selected = true;
else
e1.value = def;
}
if (e2 != null) {
if (e2.options)
e2.options[0].selected = true;
else
e2.value = def;
}
if (e3 != null) {
if (e3.options)
e3.options[0].selected = true;
else
e3.value = def;
}
if (e4 != null) {
if (e4.options)
e4.options[0].selected = true;
else
e4.value = def;
}
}
function moveFormElement(form, widget, relativepos, op, relfirst, id) {
var array = form.elements;
var first = getFormElementPos(form,widget,id)+relfirst;
var last  = getFormElementLastPos(form, widget, true,id)+relfirst;
var pos   = first + relativepos;
// alert(id+': '+first+'->'+pos+'<-'+last);
// Move Up
if (op == "up") {
if (pos > first) { 
tmp = array[pos].value;
array[pos].value = array[pos - 1].value;
array[pos - 1].value = tmp;
} else {
tmp = array[first].value;
for(i = first; i < last; i++) {
array[i].value = array[i + 1].value;
}
array[last].value = tmp;
}
} 
// Move Down
else if (op == "down") {
if (pos < last) {
tmp = array[pos].value;
array[pos].value = array[pos + 1].value;
array[pos + 1].value = tmp;
} else {
tmp = array[last].value;
for(i = last; i > first; i--) {
array[i].value = array[i - 1].value;
}
array[first].value = tmp;
}
}
// Remove Element
else if (op == "remove") {
for(i = pos; i < last; i++) {
array[i].value = array[i + 1].value;
}
array[last].value = "";
}
}
function move2FormElement(form, widget, relativepos, op, relfirst, id) {
var array = form.elements;
// Find position -1 because we locate the second field not the first one
var first = getFormElementPos(form,widget,id) + relfirst;
var last  = getFormElementLastPos(form, widget, false,id) + relfirst;
var pos   = first + relativepos;
// Move Up
if (op == "up") {
if (pos > first) {
tmp1 = array[pos].value;
tmp2 = array[pos+1].value;
array[pos    ].value = array[pos - 2].value;
array[pos + 1].value = array[pos - 1].value;
array[pos - 2].value = tmp1;
array[pos - 1].value = tmp2;
} else {
tmp1 = array[first].value;
tmp2 = array[first+1].value;
for(i = first; i < last; i+=2) {
array[i  ].value = array[i + 2].value;
array[i+1].value = array[i + 3].value;
}
array[last].value = tmp1;
array[last+1].value = tmp2;
}
} 
// Move Down
else if (op == "down") {
if (pos < last) {
tmp1 = array[pos].value;
tmp2 = array[pos+1].value;
array[pos    ].value = array[pos + 2].value;
array[pos + 1].value = array[pos + 3].value;
array[pos + 2].value = tmp1;
array[pos + 3].value = tmp2;
} else {
tmp1 = array[last    ].value;
tmp2 = array[last + 1].value;
for(i = last; i > first; i-=2) {
array[i].value = array[i - 2].value;
array[i+1].value = array[i - 1].value;
}
array[first    ].value = tmp1;
array[first + 1].value = tmp2;
}
}
// Remove Element
else if (op == "remove") {
for(i = pos; i < last; i+=2) {
array[i].value   = array[i + 2].value;
array[i+1].value = array[i + 3].value;
}
array[last].value = "";
array[last+1].value = "";
}
}
function move3FormElement(form, widget, relativepos, op, relfirst, id) {
var array = form.elements;
// Find position -1 because we locate the second field not the first one
var first = getFormElementPos(form,widget,id) + relfirst;
var last  = getFormElementLastPos(form, widget, false, id) + relfirst;
var pos   = first + relativepos;
// Move Up
if (op == "up") {
if (pos > first) {
tmp1 = array[pos].value;
tmp2 = array[pos+1].value;
tmp3 = array[pos+2].value;
array[pos    ].value = array[pos - 3].value;
array[pos + 1].value = array[pos - 2].value;
array[pos + 2].value = array[pos - 1].value;
array[pos - 3].value = tmp1;
array[pos - 2].value = tmp2;
array[pos - 1].value = tmp3;
} else {
tmp1 = array[first].value;
tmp2 = array[first+1].value;
tmp3 = array[first+2].value;
for(i = first; i < last; i+=3) {
array[i  ].value = array[i + 3].value;
array[i+1].value = array[i + 4].value;
array[i+2].value = array[i + 5].value;
}
array[last].value = tmp1;
array[last+1].value = tmp2;
array[last+2].value = tmp3;
}
} 
// Move Down
else if (op == "down") {
if (pos < last) {
tmp1 = array[pos].value;
tmp2 = array[pos+1].value;
tmp3 = array[pos+2].value;
array[pos    ].value = array[pos + 3].value;
array[pos + 1].value = array[pos + 4].value;
array[pos + 2].value = array[pos + 5].value;
array[pos + 3].value = tmp1;
array[pos + 4].value = tmp2;
array[pos + 5].value = tmp3;
} else {
tmp1 = array[last    ].value;
tmp2 = array[last + 1].value;
tmp3 = array[last + 2].value;
for(i = last; i > first; i-=3) {
array[i].value = array[i - 3].value;
array[i+1].value = array[i - 2].value;
array[i+2].value = array[i - 1].value;
}
array[first    ].value = tmp1;
array[first + 1].value = tmp2;
array[first + 2].value = tmp3;
}
}
// Remove Element
else if (op == "remove") {
for(i = pos; i < last; i+=3) {
array[i].value   = array[i + 3].value;
array[i+1].value = array[i + 4].value;
array[i+2].value = array[i + 5].value;
}
array[last].value = "";
array[last+1].value = "";
array[last+2].value = "";
}
}
// -----------------------------------------------------------------------------
// Form Element Access 
// -----------------------------------------------------------------------------
function getFormElementCount(form, name, id){
// Get all elements
var elms  = form.elements;
var count = 0;
// Count element
for (var i = 0 ; i < elms.length ; i++){
if (elms[i].name != name)
continue;
if (!id){
count++;
continue;
}
if ((elms[i].id == id) || (elms[i].id.indexOf(id) > -1)){ // very ugly
count++;
}
}
return count;
}
function getFormElementPos(form, name, id){
// Get all elements
var elms = form.elements;
// Find out the (first) current element
for (var i = 0 ; i < elms.length ; i++){
if (elms[i].name != name)
continue;
if (!id)
return i;
if ((elms[i].id == id) || (elms[i].id == id+'0')){ // very ugly
return i;
}
}
return -1;
}
function getFormElementLastPos(form, name, first, id){
// Get all elements
var elms = form.elements;
// Find out the (last) current element
var last = -1;
for (var i = 0 ; i < elms.length ; i++){
if (elms[i].name != name){
if (last > 0 && first)
break;
continue;
}
if (!id){
last = i;
continue;
}
if (elms[i].id.indexOf(id) > -1){
last = i;
continue;
}
if (last > 0 && first)
break;
}
return last;
}
// -----------------------------------------------------------------------------
// Button 
// -----------------------------------------------------------------------------
function toggleSingleSubmitButton(evt, form, on){
// check "this" is a form, otherwise, use given form
if (this.elements) {
form = this;
}
// Enable/Disable all formButton
var elements = $(form.elements);
for (var i = 0 ; i < elements.length ; i++){
var elm = $(elements[i]);
if (!on){
if (!elm.hasClassName("formButton")) { continue; }
elm.addClassName("disabledButton");
elm.oldclick = elm.onclick;
elm.onclick  = function(event){ return false; }
} else {
if (!elm.hasClassName("disabledButton")) { continue;  }
elm.removeClassName("disabledButton");
elm.onclick  = elm.oldclick;
}
}
// Register/Unregister myself
if (!on){
form.oldsubmit = form.onsubmit;
form.onsubmit  =  function(event){ return false; }
window.onbeforeunload = null;	  // disable the warning msg put in doEditPubFooter.jsp
}
else{
form.onsubmit  =  form.oldsubmit;
}
}
function setupSingleSubmitButton(off){
// Register function
try{
var forms = document.forms;
for (var i = 0 ; i < forms.length ; i++){
var form = $(forms[i]);
if (form.hasClassName("noSingleSubmitButton"))
continue;
if (off){
toggleSingleSubmitButton(null, forms[i], true);
continue;
}
var onsubmit = form.onsubmit;
if (typeof onsubmit == 'function') {
form.onsubmit = function(evt){
toggleSingleSubmitButton(evt, this);
return onsubmit(evt, this);
};
}
else{
form.onsubmit = toggleSingleSubmitButton;
}
}
} catch(ex){ alert(ex); }
}
function restrictToNumerics(input) {
var re = new RegExp("[^0-9]");
var value = input.value;
var cleaned = value.replace(re, "");
input.value = cleaned;
}
// -----------------------------------------------------------------------------
// Form 
// -----------------------------------------------------------------------------
/**
* form should be like: window.document.editForm
*/ 
function simpleSubmitForm(window, fullform, action, warn, anchorValue, actionValue) {
if(fullform.pageLoaded && fullform.pageLoaded.value=='false') {
alert(warn);
return;
}
for (var i = 0; i < fullform.elements.length; i++) {
if (fullform.elements[i].jcmsSubmitCallBack != null) {
fullform.elements[i].jcmsSubmitCallBack(window, fullform, action, warn, anchorValue);
}
}
if (anchorValue){
fullform.anchor.value = anchorValue;
}
if (action && fullform.action){
fullform.action.name  = action;
if (actionValue)
fullform.action.value = actionValue;
}
if (fullform.onsubmit)
fullform.onsubmit();
fullform.submit();
}
function confirmSubmitForm(window, fullform, action, msg, warn, anchorValue, actionValue) {
if (top.confirm(msg)) {
simpleSubmitForm(window, fullform, action, warn, anchorValue, actionValue);
}
}
function getFormName(document, form){
if (document.all){
if (form.attributes){
if (form.attributes.getNamedItem){
return form.attributes.getNamedItem("NAME").value;
}
else{
if (form.attributes["name"])
return form.attributes["name"];
else if (form.attributes["NAME"])
return form.attributes["NAME"];
else
return 'editForm';
}
}
else{
return 'editForm';
}
}
else{
return form.getAttribute("NAME");
}
}
// -----------------------------------------------------------------------------
// EditPubFooter: DEPRECATED Should be removed or replaced
// -----------------------------------------------------------------------------
function submitForm(action, anchor, actionvalue) {  
simpleSubmitForm(window, window.document.editForm, action,'Error',anchor, actionvalue);
}
function confirmSubmit(msg, action, anchor, actionvalue) {
confirmSubmitForm(window, window.document.editForm, action, msg, anchor, actionvalue)
}
function submitAction(action, value) {
simpleSubmitForm(window, window.document.editForm, action,'Error',null, value);
}
/* This function are no longer used in JCMS 5.5
function removeField(element, anchor) {
element.value = "__remove__";
submitForm("opRefresh", anchor);
}
function removeSelectedIndex(element, anchor) {
element.options[element.selectedIndex].value = "__remove__";
submitForm("opRefresh", anchor);
}
function clearSelectedIndex(element) {
element.selectedIndex=0;
}
function validateListItem(action, list, pos) {
window.document.editForm.opItem.name = action;
window.document.editForm.opItem.value = list;
window.document.editForm.itemPos.value = pos;
submitForm("opRefresh", list);
}
*/
/* js/treecat.js */
// ------------------------------------------------------------------------------------
//  AJAX TREE PACKAGE
//
//  TODO: Use new prototype function $().xxx() instead of Element.xxx()
//  TODO: Try to use JcmsJsonRequest
// ------------------------------------------------------------------------------------
Ajax.Tree = {
enableDragNDrop: true, 
dragdropArray: $A(new Array()),
// ------------------------------------------------------------------------------------
//  AJAX Function
// ------------------------------------------------------------------------------------
/**
* Get HTML of children 
* - for the img.id
* - for the full tree with given checkedArray
* 
* Update UL innerHTML with this new content.
* Remove Image click function to toggleVisibility instead of calling a new Ajax call.
* 
* @param img the clicked image
* @param ajaxSuffix String that represents the main UL id
* @param ul the root branch to fill
* @param checkedArray a Array of checked category ids
*/
downloadChildren: function(img, ajaxSuffix, ul, checkedArray, openedArray, customCallback) {
JcmsLogger.debug('TreeCat','downloadChildren():', ajaxSuffix, img, checkedArray, openedArray);
// Init Json Request
var jsonRequest = new JcmsJsonRequest(img); 
// Init RPC with jsonRequest
var funcRPC = function(){
if (img){
Ajax.Tree._getRpcTree(ajaxSuffix).getChildren(jsonRequest.asyncJsonCallBack.bind(jsonRequest), img.id);
} else {
Ajax.Tree._getRpcTree(ajaxSuffix).getChildren(jsonRequest.asyncJsonCallBack.bind(jsonRequest),checkedArray,openedArray);
}
}
// Init Callback with jsonRequest
var funcCallback = function(returnValue){
if (!returnValue){
ul.parentNode.removeChild(ul);
return;
}
// Clean
Ajax.Tree._disposeUL(ul);
Util.cleanDOMElements(ul,true);
ul.innerHTML = returnValue;
// Update Link
if (img && !img.observed){
img.onclick  = null;
img.observed = true;
Event.observe(img,'click',function(event){ Ajax.Tree.toggleOpenClose(Event.element(event)); });
}
// Update DragDrop
if($(ajaxSuffix).hasClassName('dragdrop') && Ajax.Tree.enableDragNDrop){
setTimeout(function(){ Ajax.Tree._initDragDrop(ul); },10);
}
// Call custom callback
if (customCallback){
customCallback();
}
}
// Init custom exception handle
var funcException = function(){
ul.parentNode.removeChild(ul);
Ajax.Tree.toggleOpenClose(img);
}
// Run JSON Request
jsonRequest.rpc       = funcRPC;
jsonRequest.callback  = funcCallback;
jsonRequest.exception = funcException;
jsonRequest.asyncJsonCall();
},  
/**
* Rename the given category using ajax call
* Refresh the full category tree in ajax
* 
* @param ajaxSuffix String that represents the main UL id
* @param catId The JCMS Category id
* @param value The new category name in current language
*/
rename: function(ajaxSuffix, catId, value){
JcmsLogger.debug('TreeCat','rename():', ajaxSuffix, catId, value);
// Init Json Request
var jsonRequest = new JcmsJsonRequest(); 
// Init RPC with jsonRequest callback
var funcRPC = function(){
Ajax.Tree._getRpcTree(ajaxSuffix).rename(function(msg){ Ajax.Tree._handleRPCResponse(jsonRequest, msg, ajaxSuffix); }, catId, value);
};
// Run JSON Request
jsonRequest.rpc      = funcRPC;
jsonRequest.callback = Ajax.Tree._callbackRefresh;
jsonRequest.asyncJsonCall();
},
/**
* Add a new category using ajax call
* Refresh the full category tree in ajax
* 
* @param ajaxSuffix String that represents the main UL id
* @param catId The JCMS Category id
* @param value The category name to add in current language
*/
addSubCat: function(ajaxSuffix, catId, value){
JcmsLogger.debug('TreeCat','addSubCat():', ajaxSuffix, catId, value);
// Init Json Request
var jsonRequest = new JcmsJsonRequest(); 
// Init RPC with jsonRequest callback
var funcRPC = function(){
Ajax.Tree._getRpcTree(ajaxSuffix).addSubCat(function(msg){ Ajax.Tree._handleRPCResponse(jsonRequest, msg, ajaxSuffix); },catId, value);
};
// Run JSON Request
jsonRequest.rpc        = funcRPC;
jsonRequest.callback   = function(returnValue, returnEffect){ Ajax.Tree._callbackRefresh(returnValue, returnEffect, catId); };
jsonRequest.asyncJsonCall();
},
/**
* Add a sibling category using ajax call
* Refresh the full category tree in ajax
* 
* @param ajaxSuffix String that represents the main UL id
* @param catId The JCMS Category id
* @param value The category name to add in current language
*/
addSiblingCat: function(ajaxSuffix, catId, value){
JcmsLogger.debug('TreeCat','addSiblingCat():', ajaxSuffix, catId, value);
// Init Json Request
var jsonRequest = new JcmsJsonRequest(); 
// Init RPC with jsonRequest callback
var funcRPC = function(){
Ajax.Tree._getRpcTree(ajaxSuffix).addSiblingCat(function(msg){ Ajax.Tree._handleRPCResponse(jsonRequest, msg, ajaxSuffix); },catId, value);
};
// Run JSON Request
jsonRequest.rpc        = funcRPC;
jsonRequest.callback   = function(returnValue, returnEffect){ Ajax.Tree._callbackRefresh(returnValue, returnEffect); };
jsonRequest.asyncJsonCall();
},
/**
* Remove a category using ajax call
* Refresh the full category tree in ajax
* 
* @param ajaxSuffix String that represents the main UL id
* @param catId The JCMS Category id
*/
remove: function(ajaxSuffix, catId){
JcmsLogger.debug('TreeCat','remove():', ajaxSuffix, catId);
// Init Json Request
var jsonRequest = new JcmsJsonRequest(); 
// Init RPC with jsonRequest callback
var funcRPC = function(){
Ajax.Tree._getRpcTree(ajaxSuffix).remove(function(msg){ Ajax.Tree._handleRPCResponse(jsonRequest, msg, ajaxSuffix); },catId);
};
// Run JSON Request
jsonRequest.rpc        = funcRPC;
jsonRequest.callback   = Ajax.Tree._callbackRefresh;
jsonRequest.asyncJsonCall();
},
/**
* Remove a category using ajax call
* Refresh the full category tree in ajax
* 
* @param ajaxSuffix String that represents the main UL id
* @param catId The JCMS Category id
*/
setParent: function(ajaxSuffix, catId, parentId){
JcmsLogger.debug('TreeCat','setParent():', ajaxSuffix, catId, parentId);
// Init Json Request
var jsonRequest = new JcmsJsonRequest(); 
// Init RPC with jsonRequest callback
var funcRPC = function(){
Ajax.Tree._getRpcTree(ajaxSuffix).setParent(function(msg){ Ajax.Tree._handleRPCResponse(jsonRequest, msg, ajaxSuffix); },catId, parentId);
};
// Run JSON Request
jsonRequest.rpc        = funcRPC;
jsonRequest.callback   = function(returnValue, returnEffect){ Ajax.Tree._callbackRefresh(returnValue, returnEffect, parentId); };
jsonRequest.asyncJsonCall();
},
/**
* Refresh an Ajax TreeCat
* 1. Parse tree to record checked nodes.
* 2. Remove all children of main branch.
* 3. Retrieve a new Tree using Ajax.Tree.downloadChildren
* 4. Update main branch
* 
* If UL.TreeCat have className 'follow' then the tree will open (not select)
* the given branch ids then follow the Ahref link.
* 
* @param ajaxSuffix String that represents the main UL id
* @param ids an array of ids to add to checked/open elements
*        or a single id (that will follow url after refresh)
*/
refresh: function(ajaxSuffix, ids){
JcmsLogger.debug('TreeCat','refresh():',ajaxSuffix,ids);
Ajax.setWaitState(true);
var ul = $(ajaxSuffix);
// Search checked categories
var openedArray  = new Array();
var checkedArray = new Array();
$A(ul.getElementsByTagName('INPUT')).each(function(elm, idx){
if (elm.checked){
checkedArray.push(elm.value);
}
});
// Search opened nodes
$A(ul.getElementsBySelector('LI.open')).each(function(elm, idx){
var node = elm.down();
if (node){
openedArray.push(node.id);
JcmsLogger.debug('TreeCat','Opened:',node.id);
}
});
// Add given additional checked ids
if (ids){
if (ul.hasClassName('follow')){
openedArray = openedArray.concat(ids);
}
else{
checkedArray = checkedArray.concat(ids);
}
}
// Removing all children
Ajax.Tree._disposeUL(ul);
Util.cleanDOMElements(ul,true);
// Append message
ul.innerHTML = "<li><img src='s.gif' class='loading'/> Loading...</li>";
// Prepare custom callback follow
var customCallback = null;
if (ul.hasClassName('follow') && ids && !(ids instanceof Array)){
customCallback = function(){  Ajax.Tree._followRefreshCallback(ids); }
}
// Dowload children  
Ajax.Tree.downloadChildren(null, ajaxSuffix, ul, checkedArray, openedArray, customCallback);
},
/**
* Called by refresh() for Treecat with class 'follow'
* @param ids the id to work with to find URL to follow
*/
_followRefreshCallback: function(ids){
var img   = $(ids);
if (!img){
JcmsLogger.warn('TreeCat','Id not found',ids);
return;
}
var ahref = img.next('A');
if (ahref){
document.location = ahref.href;
}
},
// ------------------------------------------------------------------------------------
//  Utility Function
// ------------------------------------------------------------------------------------
/**
* Makes AJAX call to import all the children 
* for the given img LI and given AJAX suffix.
* 
* @param img the clicked image
* @param ajaxSuffix String that represents the main UL id
*/
importChildren: function(img, ajaxSuffix) {
var li       = img.parentNode;
var ul       = document.createElement('UL');
Ajax.setWaitState(true,img);
// Set wait icon
ul.innerHTML = "<li><img src='s.gif' class='loading'/> Loading...</li>";
li.appendChild(ul);
// Open Node
Ajax.Tree.toggleOpenClose(img);
// Asynchronous call
Ajax.Tree.downloadChildren(img, ajaxSuffix, ul);
},
/**
* Toggles className 'open' and 'close' on parent LI of image.
* 
* @param img the clicked image
*/
toggleOpenClose: function(img) {
var li = img.parentNode;
if (Element.hasClassName(li,'close')){
Element.removeClassName(li,'close');
Element.addClassName(li,'open');
}
else{
Element.removeClassName(li,'open');
Element.addClassName(li,'close');
}
},
/**
* Returns the ajaxSuffix of the parent UL of 
* the given element.
* 
* @param the children element
*/
getAjaxSuffix: function(elm){
if (!elm){
return;
}
var elm = $(elm);
var ul = elm.up('UL.TreeCat');
if (!ul){
return;
}
JcmsLogger.debug('TreeCat','getAjaxSuffix():', ul.id);
return ul.id;
},
/**
* Returns the category id for the given element
* 
* @param elm the element to work with
*/
getCategoryId: function(elm){
if (!elm){
return;
}
if (elm.tagName == 'LI'){
return Ajax.Tree.getCategoryId(elm.down(0));
}
else if (elm.tagName == 'IMG'){
return elm.id;
}
else{
return Ajax.Tree.getCategoryId(elm.up('UL.TreeCat LI'));
}
},
// ------------------------------------------------------------------------------------
//  Internal Function
// ------------------------------------------------------------------------------------
/**
* Returns the correct JSON-RPC AjaxTree from given ajaxSuffix
* 
* @param ajaxSuffix the ajaxSuffix or null
*/
_getRpcTree: function(ajaxSuffix){
if (!ajaxSuffix){
return JcmsJsContext.getJsonRPC().AjaxTree;
}
else {
return JcmsJsContext.getJsonRPC()['AjaxTree'+ajaxSuffix];
}
},
/**
* Convenient callback function called to refresh 
* treecat after json-rpc call
* 
* @param ajaxSuffix the ajaxsuffix used to refresh tree
* @param returnEffect the Effect (not used)
*/
_callbackRefresh: function(ajaxSuffix, returnEffect, openId){ 
JcmsLogger.debug('TreeCat','Callback Refresh',ajaxSuffix,returnEffect,openId);
if (ajaxSuffix){
if (openId){
var ids = new Array();
ids.push(openId);
Ajax.Tree.refresh(ajaxSuffix, ids);
}
else {
Ajax.Tree.refresh(ajaxSuffix);
}
}
},
/**
* Convenient function used to handle RPC reponse.
* If RPC returns a message then call alert and finish JsonRequest job
* else finish JsonRequest Job with the given return value.
* 
* @param msg the error message
* @param returnValue the value to return if there is no errors
*/
_handleRPCResponse: function(jsonRequest, msg, returnValue){
if (msg){
alert(msg);
jsonRequest.asyncJsonCallBack();
return;
}
jsonRequest.asyncJsonCallBack(returnValue);
},
/**
* Init Sortable on TreeCat
*/
_initTreeCat: function(){
JcmsLogger.info('TreeCat','Init TreeCat');
if (!Ajax.Tree.enableDragNDrop){
return;
}
$$('UL.TreeCat').each(function(elm, idx){  
if (elm.hasClassName('dragdrop')){
Ajax.Tree._initDragDrop(elm);
}
});
},
/**
* Clean the cached dragdropArray
*/
dispose: function(){
// Because underlaying function only dispose DrangNDrop
if (!Ajax.Tree.enableDragNDrop){
return;
}
$$('UL.TreeCat').each(function(elm, idx){ 
Ajax.Tree._disposeUL(elm);
});
Ajax.Tree.dragdropArray.clear();
},
/**
* Clean LI items
* 
* @param li the li to clean
*/
_disposeLI: function(li){
// Remove previous draggable
if (li.draggable){
li.draggable.destroy();
li.draggable = null;
}
// Remove previous droppable
Droppables.remove(li);
},
/**
* Remove all drag/drop object bind to LIs under given UL
* 
* @param ul the ul element to work with
*/
_disposeUL: function(ul){
var ul = $(ul);
// Remove LI Drag/Drop
$A(ul.getElementsByTagName('LI')).each(function(li,idx){
Ajax.Tree._disposeLI(li);
Ajax.Tree.dragdropArray.splice(idx,1);
});
// Remove onclick events
$A(ul.getElementsByTagName('A')).each(function(ahref,idx){
ahref.onclick = null;
});
},
/**
* Inits all drag/drop object bind to LIs under given UL
* 
* @param ul the ul element to work with
*/
_initDragDrop: function(ul){
var ul = $(ul);
$A(ul.getElementsByTagName('LI')).each(function(li,idx){
var li = $(li);
var anchor = li.down('IMG.visual');
Event.observe(anchor,'mousedown',Ajax.Tree._lazyDrag);
// Init Droppable
Droppables.remove(li);
Droppables.add(li,{greedy:false, onHover:Ajax.Tree._onHover, onDrop:Ajax.Tree._onDrop});
// Cache LI's for clean purpose
Ajax.Tree.dragdropArray.push(li);
});
},
/**
* Used by _initDragDrop() to lazy initialise draggable onmousedown
* @param event the mousedown event
*/
_lazyDrag: function(event){
var anchor = Event.element(event);
JcmsLogger.debug('TreeCat','_lazyDrag',anchor);
// Destroy previous Draggable
var li  = anchor.up('LI');
if (li.draggable){
li.draggable.destroy();
}
// Init new Draggable
li.draggable = new Draggable(li,{revert: true, handle:'visual'});
// Remove observer
Event.stopObserving(anchor,'mousedown',Ajax.Tree._lazyDrag);
// Kick start dnd
li.draggable.initDrag(event);
Draggables.updateDrag(event);
},
/**
* Convenient internal function to stop Drag/Drop events
* 
* @param event the event
*/
_stopEvent: function(event){
Event.stop(event);
},
/**
* Internal function called by _initDragDrop()
* 
* @param dragElm the object that encapsulate the real element
*/
_onChange: function(dragElm){
// Skip quickly
if (!dragElm.element.dragObserver){
JcmsLogger.debug('TreeCat','Start dragObserver');
Event.observe(dragElm.element, 'click', Ajax.Tree._stopEvent);
dragElm.element.dragObserver = true;
}
},
/**
* Internal function called by _initDragDrop()
* 
* @param dragElm Dragged element
* @param dropElm Dropped element
* @param overlap Percetage of overlaping
*/
_onHover: function(dragElm, dropElm, overlap){
// Skip quickly
if (dropElm.className.indexOf('droppable') >= 0){
return;
}
// Remove previous droppable if item changes
if (dragElm.oldDropElm && dragElm.oldDropElm != dropElm){
dragElm.oldDropElm.removeClassName('droppable');
}
// Do not highlight it's own parent
// if (dragElm.up('LI') == dropElm){
//   return;
// }
// Add class name
dropElm.addClassName('droppable');
dragElm.oldDropElm = dropElm;
},
/**
* Internal function called by _initDragDrop()
* 
* @param dragElm Dragged element
* @param dropElm Dropped element
* @param event the Drag/Drop event
*/
_onDrop: function(dragElm, dropElm, event){
// Stop event handler
// JcmsLogger.debug('TreeCat','Stop dragObserver');
// Event.stopObserving(dragElm, 'click', Ajax.Tree._stopEvent);
// Remove previous droppable if item changes
if (dragElm.oldDropElm){
dragElm.oldDropElm.removeClassName('droppable');
}
// Do not work on parent element
if (dragElm.up('LI') == dropElm){
return;
}
// Ask question
var dnd = top.confirm(I18N.glp('msg.confirm.dragdrop'));
// Make AJAX Call
if (dnd){
dragElm.hide();  // Hide element
Ajax.Tree.setParent(Ajax.Tree.getAjaxSuffix(dragElm), 
Ajax.Tree.getCategoryId(dragElm), 
Ajax.Tree.getCategoryId(dropElm));
}
}
}
// ------------------------------------------------------------------------------------
//  EVENT OBSERVER
// ------------------------------------------------------------------------------------
Event.observe(window, 'load'  , function() { setTimeout(Ajax.Tree._initTreeCat,10); });
if (navigator.appVersion.match(/\bMSIE\b/)){
Event.observe(window, 'unload', function() { Ajax.Tree.dispose(); }, false);
}
/* js/jalios/widget/autocomplete.js */
// -----------------------------------------------------------------------------
//  INITIALISATION
// -----------------------------------------------------------------------------
Event.observe(window, 'load' , function() { setTimeout(function(){ Ajax.Autochooser.initChoosers();} ,1); });
// -----------------------------------------------------------------------------
//  AUTOCHOOSER
// -----------------------------------------------------------------------------
Ajax.Autochooser = {
/**
* Inits language specifics AutoChooser properties
*/
initLanguage: function(){
if (I18N.lang == 'en'){
I18N['info.msg.autocomplete']      = 'Enter searched text';
I18N['info.msg.autocomplete.done'] = 'Category selected !';
}
else if (I18N.lang == 'fr'){
I18N['info.msg.autocomplete']      = 'Entrer le texte à rechercher';
I18N['info.msg.autocomplete.done'] = 'Catégorie sélectionnée';
}
},
/**
* Inits (lazy) all elements matching DIV.DataChooser INPUT.formChooserLabelfield.
* Inits all TreeCats.
* 
* @see Ajax.Autochooser._initElement
*/
initChoosers: function(){
JcmsLogger.info("Autochooser","Init Autochooser Manager");
Ajax.Autochooser.initLanguage(); 
// Create div to populate
Ajax.Autochooser.autoCompleteDiv = $(document.createElement('DIV'));
Ajax.Autochooser.autoCompleteDiv.addClassName('autocomplete');
document.body.appendChild(Ajax.Autochooser.autoCompleteDiv);
$$('DIV.DataChooser INPUT.formChooserLabelfield').each(function(elm,idx){
Ajax.Autochooser._initElement(elm);
});
// TreeCat
Ajax.Autochooser._initTreecat();
},
// --------------------------------------------------
//  INIT FUNCTIONS
// --------------------------------------------------
/**
* Lazy initialisation of Aucompleter. 
* Called only on click on the input
* 
* @param elm the clicked input
*/
_initChoosersLazy: function(elm){
JcmsLogger.info("Autochooser","Init Autochooser Lazy");
// Retrieve the enclosing div type
var field = elm.up('DIV.DataChooser');
if (!field){
return;
}
// Retrieve Chooser type
var type = field.className.match(/UI_EDITOR_\S+/);
if (!type){
return;
}
// Init the right autocompleter
if ('UI_EDITOR_PUBLICATIONCHOOSER' == type){
Ajax.Autochooser._initPublications(elm, field);
} else if ('UI_EDITOR_CATEGORYCHOOSER' == type){
Ajax.Autochooser._initCategories(elm, field);
} else if ('UI_EDITOR_GROUPCHOOSER' == type){
Ajax.Autochooser._initGroups(elm, field);
} else if ('UI_EDITOR_MEMBERCHOOSER' == type){
Ajax.Autochooser._initMembers(elm, field);
} else if ('UI_EDITOR_WORKSPACECHOOSER' == type){
Ajax.Autochooser._initWorkspace(elm, field);
}
},
/**
* Init the Chooser InputFormLabel
* - Set input enabled
* - Add class name 'autocomplete'
* - Bind onClick a lazy autocompleter initialisation
* 
* @see Ajax.Autochooser._initChoosersLazy
* @param input The element to initialise
*/
_initElement: function(input){
input = $(input);
input.disabled = '';
input.addClassName('autocomplete');
var observer = function() { 
Event.stopObserving(input, 'mousedown' , observer);
Ajax.Autochooser._initChoosersLazy(input); 
};
Event.observe(input, 'mousedown' , observer);
},
/**
* Init all publication choosers
*/
_initPublications: function(input, field){
var type = Ajax.Autochooser._getChooserContentType(field);
// Debug
if (JcmsLogger.isDebug && JcmsLogger.Autochooser){
var inputName = input.next('INPUT.formChooserfield').name;
JcmsLogger.debug("Autochooser",inputName+" Type:",type);
}
Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acpublication.jsp?type="+type);
},
/**
* Init all member choosers
*/
_initMembers: function(input, field){
// Retrieve the enclosing div groups
var gids = Ajax.Autochooser._getChooserGroups(field); 
// Debug
if (JcmsLogger.isDebug && JcmsLogger.Autochooser){
var inputName = input.next('INPUT.formChooserfield').name;
JcmsLogger.debug("Autochooser",inputName+" Groups:",gids);
}
Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acmember.jsp?"+gids);
},
/**
* Init all groups choosers
*/
_initGroups: function(input, field){
// Retrieve the enclosing div groups
var gids = Ajax.Autochooser._getChooserGroups(field); 
// Debug
if (JcmsLogger.isDebug && JcmsLogger.Autochooser){
var inputName = input.next('INPUT.formChooserfield').name;
JcmsLogger.debug("Autochooser",inputName+" Groups:",gids);
}
Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acgroup.jsp?"+gids);
},
/**
* Init all category choosers
*/
_initCategories: function(input, field){
Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/accategory.jsp");
},
/**
* Init all workspace choosers
*/
_initWorkspace: function(input, field){
Ajax.Autochooser._newAutocompleter(input,"jcore/autocomplete/acworkspace.jsp");
},
/**
* Instanciate a new Scriptaculous AJAX Autocompleter
*/
_newAutocompleter: function(input, url){
new Ajax.Autocompleter(input,Ajax.Autochooser.autoCompleteDiv, url, {paramName: 'autocomplete', minChars: 2, afterUpdateElement: Ajax.Autochooser._populate });
},
/**
* Init all treecat
*/
_initTreecat: function(){
$$('UL.TreeCat').each(function(elm,idx){
elm = $(elm);
// Treecat must declare "autocomplete" class
if (!elm.hasClassName('autocomplete')){
return;
}
// Check texfield doesn't already exists
var tfId = elm.id+'_autocomplete';
var tf = $(tfId);
if (tf){
tf.value = I18N.glp('info.msg.autocomplete');
return;
}
// Create textfield for autocompleter
var textfield      = document.createElement("INPUT");
textfield.type      = 'text';
textfield.className = 'formTextfield autocomplete treecatcomplete';
textfield.treecat   = elm.id;
textfield.value     = I18N.glp('info.msg.autocomplete');
textfield.id        = tfId
// Append textfield before TreeCat
elm.parentNode.insertBefore(textfield, elm);
Event.observe(textfield, 'click', function(){ textfield.value = ""; });
// Bind an ajax autocompleter
new Ajax.Autocompleter(textfield,Ajax.Autochooser.autoCompleteDiv,"jcore/autocomplete/accategory.jsp?cids="+elm.id, {paramName: 'autocomplete', minChars: 2, afterUpdateElement: Ajax.Autochooser._populateTreeCat });
});
},
// --------------------------------------------------
//  CLASS PARSING FUNCTIONS
// --------------------------------------------------
/**
* Parses classes of the given field to look for
* the publication chooser type.
* 
* The matching classes should be Type_PType (ie Type_Article).
* This classe is generated by the widget.
* 
* @param field the enclosing DIV
* @return String the JCMS type of the chooser
*/
_getChooserContentType: function(field){
var type  = field.className.match(/Type_\S+/);
if (!type){
JcmsLogger.warn("Autochooser","Missing Publication chooser type");
return;
}
return type.toString().substr(5);
},
/**
* Parses classes of the given field to look for
* parameter gids (parent groups id).
* 
* The matching classes should be gids_GroupId (ie gids_c_1234).
* This classe is generated by the widget parsing chooserQS.
* 
* @param field the enclosing DIV
* @return String the JCMS parent groups of the chooser
*/
_getChooserGroups: function(field){
var gids  = field.className.match(/gids_\S+/g);
if (!gids){
return "";
}
var gids  = gids.join('&').replace(/gids_/g,'gids=');
return gids;
},
// --------------------------------------------------
//  CALLBACK FUNCTIONS
// --------------------------------------------------
/**
* 
* @param li the item to check
*/
_checkItem: function(input, li){
var li = $(li);
if (li.hasClassName('info')){
input.value = I18N.glp('info.msg.autocomplete');
return false;
}
if (li.hasClassName('nomatch')){
input.value = I18N.glp('info.msg.autocomplete');
return false;
}
return true;
},
/**
* Callback used by Chooser Autocompleter. Called when a 
* selection has been done.
* 
* @param input the form chooser label input
* @param li the selected LI tag
*/
_populate: function(input,li){
var input = $(input);
if (!Ajax.Autochooser._checkItem(input, li))
return;
var chooser = input.next('INPUT.formChooserfield');
chooser.value = li.id.substring(5);
},
/**
* Callback used by TreeCat Autocompleter. Called when a 
* selection has been done.
* 
* @param input the form chooser label input
* @param li the selected LI tag
*/
_populateTreeCat: function(input,li){
var input = $(input);
if (!Ajax.Autochooser._checkItem(input, li))
return;
input.value = I18N.glp('info.msg.autocomplete.done');
input.addClassName('treecatrefresh');
input.blur();
setTimeout(function(){
input.value = I18N.glp('info.msg.autocomplete');
input.removeClassName('treecatrefresh');
},2000);
Ajax.Tree.refresh(input.treecat, li.id.substring(5));
}
}
/* js/jalios/textarea-resizer.js */
/*
** Adds automatic resizing and resize handle below
** all textareas with "resizable" class.
*/
function TextAreaResizer(elt) {
this.textarea = elt;
this.create();
}
TextAreaResizer.prototype = {
create : function() {
// Create handle and insert just after textarea
this.handle = document.createElement("DIV");
this.handle.className = "textarea-resizer";
this.handle.title = I18N.glp('ui.textarea-resizer.title');
// Modify handle size to match size of textarea
var textAreaWidth = $(this.textarea).getDimensions().width;
if (textAreaWidth > 0 ) {
this.handle.style.width = (textAreaWidth - 2) + "px";
}
// insert handle
this.textarea.parentNode.insertBefore(this.handle, this.textarea.nextSibling);
// Add custom style to text area
$(this.textarea).addClassName("textarea-resized");
this.dragStartHdlr = function(evt){this.dragStart(evt);}.bind(this);
this.dragMoveHdlr = function(evt){this.dragMove(evt);}.bind(this);
this.dragStopHdlr = function(evt){this.dragStop(evt);}.bind(this);
this.autoResizeHdlr = function(evt){this.autoResize(evt);}.bind(this); 
Event.observe(this.handle, 'mousedown', this.dragStartHdlr);
Event.observe(this.textarea, 'keyup', this.autoResizeHdlr);
},
dragStart : function(evt) {
this.hasBeenResized = true;
this.dragStartY = Event.pointerY(evt);
this.dragStartH = $(this.textarea).getDimensions().height;
Event.observe(document, 'mousemove', this.dragMoveHdlr);
Event.observe(document, 'mouseup', this.dragStopHdlr);
},
dragMove : function(evt) {
var newHeight = this.dragStartH + Event.pointerY(evt) - this.dragStartY ;
if (newHeight > 15) {
this.textarea.style.height = newHeight + "px";
}
},
dragStop : function(evt) {
Event.stopObserving(document, "mousemove", this.dragMoveHdlr);
Event.stopObserving(document, "mouseup", this.dragStopHdlr);
},
autoResize : function(evt) {
if (this.hasBeenResized) {
return;
};
var ta = this.textarea;
var lines = ta.value.split('\n');
var rows = 1;
for (i = 0; i < lines.length; i++) {
if (lines[i].length >= ta.cols) { 
rows += Math.floor(lines[i].length / ta.cols);
}
}
rows += lines.length;
if (rows > ta.rows && rows < 20) {
ta.rows = rows;
}
}
};
function initTextAreaResizer() {
if ( document.TextAreaResizerDone ) { return; }
document.TextAreaResizerDone = true;
$A(document.getElementsByTagName("TEXTAREA")).each(function(textarea) {
if (textarea.className.indexOf("resizable") != -1) {
new TextAreaResizer(textarea);
}
});
}
/* js/custom.js */
// Put your custom scripts here
// Sample code registering rule effect on Message Box
// Add to your JSP: jcmsContext.addJSHeader("js/lib/event-selectors.js");
/*
var rules1 = {
'DIV.mboxWarning' : function(element){
new Effect.Shake(element);
}
}
EventSelectors.register(rules1);
*/
