// Functions related to user authentication function cookiesAreEnabled() { // Test whether cookies are enabled by attempting to set a cookie and then // change its value var c = "areYourCookiesEnabled=0"; document.cookie = c; var dc = document.cookie; // Cookie not set? Fail if (dc.indexOf(c) == -1) return 0; // Change test cookie c = "areYourCookiesEnabled=1"; document.cookie = c; dc = document.cookie; // Cookie not changed? fail if (dc.indexOf(c) == -1) return 0; // Delete cookie document.cookie = "areYourCookiesEnabled=; expires=Thu, 01-Jan-70 00:00:01 GMT"; return 1; } function setLoginVars() { // Indicate if JS is enabled document.getElementById('js_enabled').value = 1; // Indicate if cookies are enabled document.getElementById('cookies_enabled').value = cookiesAreEnabled(); // Copy login and password length to alternative vars since current vars will // be removed from the request by zope's authentication mechanism. document.getElementById('login_name').value = document.getElementById('__ac_name').value; password = document.getElementById('__ac_password'); emptyPassword = document.getElementById('pwd_empty'); if (password.value.length==0) emptyPassword.value = '1'; else emptyPassword.value = '0'; } function showLoginForm() { // Hide the login link. var loginLink = document.getElementById('loginLink'); loginLink.style.display = "none"; // Displays the login form. var loginFields = document.getElementById('loginFields'); loginFields.style.display = "inline"; } function goto(url) { window.location = url } function switchLanguage(selectWidget) { var language = selectWidget.options[selectWidget.selectedIndex].value; goto("/config/changeLanguage?language=" + language); } var isIe = (navigator.appName == "Microsoft Internet Explorer"); function getElementsHavingName(tag, name) { if (!isIe) return document.getElementsByName(name); var elems = document.getElementsByTagName(tag); var res = new Array(); for (var i=0; i<\/div>"); } if (xhrObjects[pos].xhr.readyState == 4) { // We have received the HTML chunk var hookElem = document.getElementById(hook); if (hookElem && (xhrObjects[pos].xhr.status == 200)) { injectChunk(hookElem, xhrObjects[pos].xhr.responseText); // Call a custom Javascript function if required if (xhrObjects[pos].onGet) { xhrObjects[pos].onGet(xhrObjects[pos], hookElem); } // Eval inner scripts if any. var innerScripts = getElementsHavingName('div', 'appyHook'); for (var i=0; i:, the PX will be found on the field named instead of being found directly on the object at p_url. p_hook is the ID of the XHTML element that will be filled with the XHTML result from the server. p_beforeSend is a Javascript function to call before sending the request. This function will get 2 args: the XMLHttpRequest object and the p_params. This method can return, in a string, additional parameters to send, ie: "¶m1=blabla¶m2=blabla". p_onGet is a Javascript function to call when we will receive the answer. This function will get 2 args, too: the XMLHttpRequest object and the HTML node element into which the result has been inserted. */ // First, get a non-busy XMLHttpRequest object. var pos = -1; for (var i=0; i < xhrObjects.length; i++) { if (xhrObjects[i].freed == 1) { pos = i; break; } } if (pos == -1) { pos = xhrObjects.length; xhrObjects[pos] = new XhrObject(); } xhrObjects[pos].hook = hook; xhrObjects[pos].onGet = onGet; if (xhrObjects[pos].xhr) { var rq = xhrObjects[pos]; rq.freed = 0; // Construct parameters var paramsFull = 'px=' + px; if (params) { for (var paramName in params) paramsFull = paramsFull + '&' + paramName + '=' + params[paramName]; } // Call beforeSend if required if (beforeSend) { var res = beforeSend(rq, params); if (res) paramsFull = paramsFull + res; } // Construct the URL to call var urlFull = url + '/ajax'; if (mode == 'GET') { urlFull = urlFull + '?' + paramsFull; } // Perform the asynchronous HTTP GET or POST rq.xhr.open(mode, urlFull, true); if (mode == 'POST') { // Set the correct HTTP headers rq.xhr.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded"); rq.xhr.setRequestHeader("Content-length", paramsFull.length); rq.xhr.setRequestHeader("Connection", "close"); rq.xhr.onreadystatechange = function(){ getAjaxChunk(pos); } rq.xhr.send(paramsFull); } else if (mode == 'GET') { rq.xhr.onreadystatechange = function() { getAjaxChunk(pos); } if (window.XMLHttpRequest) { rq.xhr.send(null); } else if (window.ActiveXObject) { rq.xhr.send(); } } } } /* The functions below wrap askAjaxChunk for getting specific content through an Ajax request. */ function askQueryResult(hookId, objectUrl, className, searchName, startNumber, sortKey, sortOrder, filterKey) { // Sends an Ajax request for getting the result of a query. var params = {'className': className, 'search': searchName, 'startNumber': startNumber}; if (sortKey) params['sortKey'] = sortKey; if (sortOrder) params['sortOrder'] = sortOrder; if (filterKey) { var filterWidget = document.getElementById(hookId + '_' + filterKey); if (filterWidget && filterWidget.value) { params['filterKey'] = filterKey; params['filterValue'] = filterWidget.value; } } askAjaxChunk(hookId, 'GET', objectUrl, 'pxQueryResult', params); } function askObjectHistory(hookId, objectUrl, maxPerPage, startNumber) { // Sends an Ajax request for getting the history of an object var params = {'maxPerPage': maxPerPage, 'startNumber': startNumber}; askAjaxChunk(hookId, 'GET', objectUrl, 'pxHistory', params); } function askRefField(hookId, objectUrl, fieldName, innerRef, startNumber, action, actionParams){ // Sends an Ajax request for getting the content of a reference field. var startKey = hookId + '_startNumber'; var params = {'innerRef': innerRef }; params[startKey] = startNumber; if (action) params['action'] = action; if (actionParams) { for (key in actionParams) { params[key] = actionParams[key]; }; } askAjaxChunk(hookId, 'GET', objectUrl, fieldName+':pxView', params); } function askField(hookId, objectUrl, layoutType, showChanges, masterValues, requestValue, error, className){ // Sends an Ajax request for getting the content of any field. var fieldName = hookId.split('_')[1]; var params = {'layoutType': layoutType, 'showChanges': showChanges}; if (masterValues) params['masterValues'] = masterValues.join('*'); if (requestValue) params[fieldName] = requestValue; if (error) params[fieldName + '_error'] = error; var px = fieldName + ':pxRender'; if (className) px = className + ':' + px; askAjaxChunk(hookId, 'GET', objectUrl, px, params, null, evalInnerScripts); } // Function used by checkbox widgets for having radio-button-like behaviour function toggleCheckbox(visibleCheckbox, hiddenBoolean) { vis = document.getElementById(visibleCheckbox); hidden = document.getElementById(hiddenBoolean); if (vis.checked) hidden.value = 'True'; else hidden.value = 'False'; } // Shows/hides a dropdown menu function toggleDropdown(dropdownId, forcedValue){ var dropdown = document.getElementById(dropdownId); // Force to p_forcedValue if specified if (forcedValue) {dropdown.style.display = forcedValue} else { var displayValue = dropdown.style.display; if (displayValue == 'block') dropdown.style.display = 'none'; else dropdown.style.display = 'block'; } } // Function that sets a value for showing/hiding sub-titles. function setSubTitles(value, tag) { createCookie('showSubTitles', value); // Get the sub-titles var subTitles = getElementsHavingName(tag, 'subTitle'); if (subTitles.length == 0) return; // Define the display style depending on p_tag. var displayStyle = 'inline'; if (tag == 'tr') displayStyle = 'table-row'; for (var i=0; i < subTitles.length; i++) { if (value == 'true') subTitles[i].style.display = displayStyle; else subTitles[i].style.display = 'none'; } } // Function that toggles the value for showing/hiding sub-titles. function toggleSubTitles(tag) { // Get the current value var value = readCookie('showSubTitles'); if (value == null) value = 'true'; // Toggle the value var newValue = 'true'; if (value == 'true') newValue = 'false'; if (!tag) tag = 'div'; setSubTitles(newValue, tag); } // Functions used for master/slave relationships between widgets function getSlaveInfo(slave, infoType) { // Returns the appropriate info about slavery, depending on p_infoType. var cssClasses = slave.className.split(' '); var masterInfo = null; // Find the CSS class containing master-related info. for (var j=0; j < cssClasses.length; j++) { if (cssClasses[j].indexOf('slave*') == 0) { // Extract, from this CSS class, master name or master values. masterInfo = cssClasses[j].split('*'); if (infoType == 'masterName') return masterInfo[1]; else return masterInfo.slice(2); } } } function getMasterValues(master) { // Returns the list of values that p_master currently has. var res = null; if ((master.tagName == 'INPUT') && (master.type != 'checkbox')) { res = master.value; if ((res.charAt(0) == '(') || (res.charAt(0) == '[')) { // There are multiple values, split it values = res.substring(1, res.length-1).split(','); res = []; var v = null; for (var i=0; i < values.length; i++){ v = values[i].replace(' ', ''); res.push(v.substring(1, v.length-1)); } } else res = [res]; // A single value } else if (master.type == 'checkbox') { res = master.checked + ''; res = res.charAt(0).toUpperCase() + res.substr(1); res = [res]; } else { // SELECT widget res = []; for (var i=0; i < master.options.length; i++) { if (master.options[i].selected) res.push(master.options[i].value); } } return res; } function getSlaves(master) { // Gets all the slaves of master. allSlaves = getElementsHavingName('table', 'slave'); res = []; masterName = master.attributes['name'].value; // Remove leading 'w_' if the master is in a search screen. if (masterName.indexOf('w_') == 0) masterName = masterName.slice(2); if (master.type == 'checkbox') { masterName = masterName.substr(0, masterName.length-8); } slavePrefix = 'slave*' + masterName + '*'; for (var i=0; i < allSlaves.length; i++){ cssClasses = allSlaves[i].className.split(' '); for (var j=0; j < cssClasses.length; j++) { if (cssClasses[j].indexOf(slavePrefix) == 0) { res.push(allSlaves[i]); break; } } } return res; } function updateSlaves(master, slave, objectUrl, layoutType, requestValues, errors, className){ /* Given the value(s) in a master field, we must update slave's visibility or value(s). If p_slave is given, it updates only this slave. Else, it updates all slaves of p_master. */ var slaves = null; if (slave) { slaves = [slave]; } else { slaves = getSlaves(master); } masterValues = getMasterValues(master); for (var i=0; i < slaves.length; i++) { slaveryValues = getSlaveInfo(slaves[i], 'masterValues'); if (slaveryValues[0] != '+') { // Update slaves visibility depending on master values. var showSlave = false; for (var j=0; j < slaveryValues.length; j++) { for (var k=0; k< masterValues.length; k++) { if (slaveryValues[j] == masterValues[k]) showSlave = true; } } if (showSlave) slaves[i].style.display = ''; else slaves[i].style.display = 'none'; } else { // Update slaves' values depending on master values. var slaveId = slaves[i].id; var slaveName = slaveId.split('_')[1]; var reqValue = null; if (requestValues && (slaveName in requestValues)) reqValue = requestValues[slaveName]; var err = null; if (errors && (slaveName in errors)) err = errors[slaveName]; askField(slaveId, objectUrl, layoutType, false, masterValues, reqValue, err, className); } } } function initSlaves(objectUrl, layoutType, requestValues, errors) { /* When the current page is loaded, we must set the correct state for all slave fields. For those that are updated via Ajax requests, their p_requestValues and validation p_errors must be carried to those requests. */ slaves = getElementsHavingName('table', 'slave'); i = slaves.length -1; while (i >= 0) { masterName = getSlaveInfo(slaves[i], 'masterName'); master = document.getElementById(masterName); // If master is not here, we can't hide its slaves when appropriate. if (master) { updateSlaves(master,slaves[i],objectUrl,layoutType,requestValues,errors);} i -= 1; } } // Function used to submit the appy form on pxEdit function submitAppyForm(button) { var theForm = document.getElementById('appyForm'); // On which button has the user clicked? theForm.button.value = button; theForm.submit(); } // Function used for triggering a workflow transition function triggerTransition(formId, transitionId, msg) { var theForm = document.getElementById(formId); theForm.workflow_action.value = transitionId; if (!msg) { theForm.submit(); } else { // Ask the user to confirm. askConfirm('form', formId, msg, true); } } function onDeleteObject(objectUid) { f = document.getElementById('deleteForm'); f.objectUid.value = objectUid; askConfirm('form', 'deleteForm', delete_confirm); } function onDeleteEvent(objectUid, eventTime) { f = document.getElementById('deleteEventForm'); f.objectUid.value = objectUid; f.eventTime.value = eventTime; askConfirm('form', 'deleteEventForm', delete_confirm); } function onUnlinkObject(sourceUid, fieldName, targetUid) { f = document.getElementById('unlinkForm'); f.sourceUid.value = sourceUid; f.fieldName.value = fieldName; f.targetUid.value = targetUid; askConfirm('form', 'unlinkForm', unlink_confirm); } function onUnlockPage(objectUid, pageName) { f = document.getElementById('unlockForm'); f.objectUid.value = objectUid; f.pageName.value = pageName; askConfirm('form', 'unlockForm', unlock_confirm); } function createCookie(name, value, days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = "; expires="+date.toGMTString(); } else expires = ""; document.cookie = name+"="+escape(value)+expires+"; path=/;"; } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i=0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0)==' ') { c = c.substring(1,c.length); } if (c.indexOf(nameEQ) == 0) { return unescape(c.substring(nameEQ.length,c.length)); } } return null; } function toggleCookie(cookieId) { // What is the state of this boolean (expanded/collapsed) cookie? var state = readCookie(cookieId); if ((state != 'collapsed') && (state != 'expanded')) { // No cookie yet, create it. createCookie(cookieId, 'collapsed'); state = 'collapsed'; } var hook = document.getElementById(cookieId); // The hook is the part of // the HTML document that needs to be shown or hidden. var displayValue = 'none'; var newState = 'collapsed'; var imgSrc = 'ui/expand.gif'; if (state == 'collapsed') { // Show the HTML zone displayValue = 'block'; imgSrc = 'ui/collapse.gif'; newState = 'expanded'; } // Update the corresponding HTML element hook.style.display = displayValue; var img = document.getElementById(cookieId + '_img'); img.src = imgSrc; // Inverse the cookie value createCookie(cookieId, newState); } // Function that allows to generate a document from a pod template. function generatePodDocument(contextUid, fieldName, podFormat, queryData, customParams) { var theForm = document.getElementById("podTemplateForm"); theForm.objectUid.value = contextUid; theForm.fieldName.value = fieldName; theForm.podFormat.value = podFormat; theForm.askAction.value = "False"; theForm.queryData.value = queryData; if (customParams) { theForm.customParams.value = customParams; } else { theForm.customParams.value = ''; } var askActionWidget = document.getElementById(contextUid + '_' + fieldName + '_cb'); if (askActionWidget && askActionWidget.checked) { theForm.askAction.value = "True"; } theForm.submit(); } function protectAppyForm() { window.onbeforeunload = function(e){ theForm = document.getElementById("appyForm"); if (theForm.button.value == "") { var e = e || window.event; if (e) {e.returnValue = warn_leave_form;} return warn_leave_form; } } } // Functions for opening and closing a popup function openPopup(popupId, msg) { // Put the message into the popup if (msg) { var confirmElem = document.getElementById('appyConfirmText'); confirmElem.innerHTML = msg; } // Open the popup var popup = document.getElementById(popupId); // Put it at the right place on the screen var scrollTop = document.body.scrollTop || window.pageYOffset || 0; popup.style.top = (scrollTop + 150) + 'px'; popup.style.display = "block"; // Show the greyed zone var greyed = document.getElementById('grey'); greyed.style.top = scrollTop + 'px'; greyed.style.display = "block"; greyed.style.height = document.body.clientHeight; greyed.style.width = document.body.clientWidth; } function closePopup(popupId) { // Close the popup var popup = document.getElementById(popupId); popup.style.display = "none"; // Hide the greyed zone var greyed = document.getElementById('grey'); greyed.style.display = "none"; } // Function triggered when an action needs to be confirmed by the user function askConfirm(actionType, action, msg, showComment) { /* Store the actionType (send a form, call an URL or call a script) and the related action, and shows the confirm popup. If the user confirms, we will perform the action. If p_showComment is true, an input field allowing to enter a comment will be shown in the popup. */ var confirmForm = document.getElementById('confirmActionForm'); confirmForm.actionType.value = actionType; confirmForm.action.value = action; var commentArea = document.getElementById('commentArea'); if (showComment) commentArea.style.display = "block"; else commentArea.style.display = "none"; openPopup("confirmActionPopup", msg); } // Function triggered when an action confirmed by the user must be performed function doConfirm() { // The user confirmed: perform the required action. closePopup('confirmActionPopup'); var confirmForm = document.getElementById('confirmActionForm'); var actionType = confirmForm.actionType.value; var action = confirmForm.action.value; if (actionType == 'form') { /* Submit the form whose id is in "action", and transmmit him the comment from the popup when relevant */ var theForm = document.getElementById(action); if ((confirmForm.comment.style.display != 'none') && (confirmForm.comment.value)) { theForm.comment.value = confirmForm.comment.value; } theForm.submit(); } // We must go to the URL defined in "action" else if (actionType == 'url') { goto(action) } else if (actionType == 'script') { // We must execute Javascript code in "action" eval(action); } } var wrongTextInput = '#F9EDBE none'; // Function triggered when the user asks password reinitialisation function doAskPasswordReinit() { // Check that the user has typed a login var theForm = document.getElementById('askPasswordReinitForm'); var login = theForm.login.value.replace(' ', ''); if (!login) { theForm.login.style.background = wrongTextInput; } else { closePopup('askPasswordReinitPopup'); theForm.submit(); } } // Function that finally posts the edit form after the user has confirmed that // she really wants to post it. function postConfirmedEditForm() { var theForm = document.getElementById('appyForm'); theForm.confirmed.value = "True"; theForm.button.value = 'save'; theForm.submit(); } // Function that shows or hides a tab. p_action is 'show' or 'hide'. function manageTab(tabId, action) { // Manage the tab content (show it or hide it) var content = document.getElementById('tabcontent_' + tabId); if (action == 'show') { content.style.display = 'table-row'; } else { content.style.display = 'none'; } // Manage the tab itself (show as selected or unselected) var left = document.getElementById('tab_' + tabId + '_left'); var tab = document.getElementById('tab_' + tabId); var right = document.getElementById('tab_' + tabId + '_right'); if (action == 'show') { left.src = "ui/tabLeft.png"; tab.style.backgroundImage = "url(ui/tabBg.png)"; right.src = "ui/tabRight.png"; } if (action == 'hide') { left.src = "ui/tabLeftu.png"; tab.style.backgroundImage = "url(ui/tabBgu.png)"; right.src = "ui/tabRightu.png"; } } // Function used for displaying/hiding content of a tab function showTab(tabId) { // 1st, show the tab to show manageTab(tabId, 'show'); // Compute the number of tabs. var idParts = tabId.split('_'); var prefix = idParts[0] + '_'; // Store the currently selected tab in a cookie. createCookie('tab_' + idParts[0], tabId); var nbOfTabs = idParts[2]*1; // Then, hide the other tabs. for (var i=0; i