CMSForm = Class.extend('ChangeTracker').extend('Observable'); CMSForm.prototype = { initialize : function(fn) { this.ChangeTracker.initialize(); this.formName = fn; this.prepareForm(); }, /** * Trigger normal save event, helpful e.g. when enter key is pressed in * single line input fields. */ onsubmit: function(e) { this.save(); Event.stop(e); return false; }, /** * Processing called whenever a page is loaded in the right - including the initial one */ prepareForm : function() { ajaxActionsAtTop(this.id, 'form_actions_' + this.formName, this.formName); // Update the nav items down the bottom if($('SwitchView') && $('AjaxSwitchView')) { $('SwitchView').innerHTML = $('AjaxSwitchView').innerHTML; $('AjaxSwitchView').innerHTML = ''; Behaviour.apply('SwitchView'); // This is needed so calendar still works } }, /** * Load actions from a string containing the HTML content */ loadActionsFromString : function(actionHTML) { var actionHolder = $('form_actions_' + this.formName); actionHolder.innerHTML = actionHTML; prepareAjaxActions(actionHolder, this.id, this.formName); }, /** * Close the form down without any corrective action, after its been deleted. */ closeIfSetTo: function(id) { if(this.elements.ID && this.elements.ID.value == id) { // Note: TinyMCE coupling tinymce_removeAll(); this.innerHTML = "<p>" + ss.i18n._t('LeftAndMain.PAGEWASDELETED') + "</p>"; } }, /** * Reload lose the form if the current page is open. */ reloadIfSetTo: function(id) { if(this.elements.ID && this.elements.ID.value == id) { this.getPageFromServer(id); } }, close: function() { this.innerHTML = "<p> </p>"; var actions; if(actions = $('form_actions_' + this.formName)) { actions.parentNode.removeChild(actions); } }, updateStatus: function( newStatus ) { if( $('Form_EditForm_Status') ) $('Form_EditForm_Status').innerHTML = "STATUS: " + newStatus; }, /** * Load a new page into the right-hand form. * * @param formContent string * @param response object (optional) * @param evalResponse boolean (optional) */ loadNewPage : function(formContent, response, evalResponse) { //alert('here: ' + formContent); var rightHTML = formContent; // Rewrite # links rightHTML = rightHTML.replace(/(<a[^>]+href *= *")#/g, '$1' + window.location.href.replace(/#.*$/,'') + '#'); // Rewrite iframe links (for IE) rightHTML = rightHTML.replace(/(<iframe[^>]*src=")([^"]+)("[^>]*>)/g, '$1' + baseHref() + '$2$3'); // Note: TinyMCE coupling tinymce_removeAll(); // Prepare iframes for removal, otherwise we get loading bugs var i, allIframes = this.getElementsByTagName('iframe'); if(allIframes) for(i=0;i<allIframes.length;i++) { allIframes[i].contentWindow.location.href = 'about:blank'; allIframes[i].parentNode.removeChild(allIframes[i]); } if(response && evalResponse) { Ajax.Evaluator(response); } else { this.innerHTML = rightHTML; } // Get the form attributes from embedded fields var attr; for(attr in {'action':true ,'method':true,'enctype':true,'name':true}) { if(this.elements['_form_' + attr]) { this[attr] = this.elements['_form_' + attr].value; this.elements['_form_' + attr].parentNode.removeChild(this.elements['_form_' + attr]); } } allIframes = this.getElementsByTagName('iframe'); if(allIframes) for(i=0;i<allIframes.length;i++) { try { allIframes[i].contentWindow.location.href = allIframes[i].src; } catch(er) { alert('Error in LeftAndMain_right.js CMSForm.loadNewPage: ' + er.message); } } _TAB_DIVS_ON_PAGE = []; //initTabstripe() become livequery in tabstrip.js, so we don't need to call it for each tab strip here. // We assume that an evaluated response is generated by FormResponse // which takes care of calling these method it if (!evalResponse) { if (this.prepareForm) this.prepareForm(); Behaviour.apply(this); } if(this.resetElements) this.resetElements(); window.ontabschanged(); // If there's a title field and it's got a "new XX" value, focus/select that first // This is really a little too CMS-specific (as opposed to LeftAndMain), but the cleanup can happen after jQuery refactoring if($('input#Form_EditForm_Title') && $('input#Form_EditForm_Title').value.match(/^new/i)) { $('input#Form_EditForm_Title').select(); } }, /** * Save the contens of the form, by submitting it and resetting is changed checker * on success. * * @param ifChanged boolean if true, only save changed fields * @param callAfter function (optional) callback function to run after the AJAX request. * @param action string (optional, default is 'save') action to call via AJAX. * @param publish boolean (optional) whether to publish in addition to saving */ save: function(ifChanged, callAfter, action, publish) { _AJAX_LOADING = true; // Note: TinyMCE coupling if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave(); if(!action) action = "save"; var __callAfter = callAfter; var __form = this; if(__form.notify && __form.elements.ID != undefined) __form.notify('BeforeSave', __form.elements.ID.value); // validate if required if(this.validate && !this.validate()) { // TODO Automatically switch to the tab/position of the first error statusMessage("Validation failed.", "bad"); if($('Form_EditForm_action_save') && $('Form_EditForm_action_save').stopLoading) $('Form_EditForm_action_save').stopLoading(); return false; } var success = function(response) { Ajax.Evaluator(response); __form.resetElements(); if(__callAfter) __callAfter(); if(__form.notify && __form.elements.ID != undefined) __form.notify('PageSaved', __form.elements.ID.value); if($('Form_EditForm_action_save') && $('Form_EditForm_action_save').stopLoading) $('Form_EditForm_action_save').stopLoading(); _AJAX_LOADING = false; } if(ifChanged) { var data = this.serializeChangedFields('ID') + '&ajax=1&action_' + action + '=1'; } else { var data = this.serializeAllFields() + '&ajax=1&action_' + action + '=1'; } if(publish) { data += '&publish=1'; } statusMessage(ss.i18n._t('CMSMAIN.SAVING'), null, true); new Ajax.Request(this.action, { method : this.method, postBody: data, onSuccess : success, onFailure : function(response) { errorMessage('Error saving content', response); if($('Form_EditForm_action_save') && $('Form_EditForm_action_save').stopLoading) $('Form_EditForm_action_save').stopLoading(); _AJAX_LOADING = false; } }); }, loadPage_url : 'admin/getpage' } CMSRightForm = Class.extend('CMSForm'); CMSRightForm.prototype = { intialize: function() { this.CMSForm.initialize('right'); }, /** * Load the given URL (with &ajax=1) into this form */ loadURLFromServer : function(url) { var urlParts = url.match( /ID=(\d+)/ ); var id = urlParts ? urlParts[1] : null; if( !url.match( /^https?:\/\/.*/ ) ) url = document.getElementsByTagName('base')[0].href + url; new Ajax.Request( url + '&ajax=1', { asynchronous : true, onSuccess : function( response ) { $('Form_EditForm').successfullyReceivedPage(response,id); }, onFailure : function(response) { alert(response.responseText); errorMessage('error loading page',response); } }); }, successfullyReceivedPage : function(response,pageID) { var loadingNode = $('sitetree').loadingNode; if( loadingNode && pageID && parseInt( $('sitetree').getIdxOf( loadingNode ) ) != pageID ) { return; } // must wait until the javascript has finished document.body.style.cursor = 'wait'; this.loadNewPage(response.responseText); var subform; if(subform = $('Form_SubForm')) subform.close(); if(this.elements.ID) { this.notify('PageLoaded', this.elements.ID.value); } if(this.receivingID) { // Treenode might not exist if that part of the tree is closed var treeNode = loadingNode ? loadingNode : $('sitetree').getTreeNodeByIdx(this.receivingID); if(treeNode) { $('sitetree').setCurrentByIdx(treeNode.getIdx()); treeNode.removeNodeClass('loading'); } statusMessage(''); } // must wait until the javascript has finished document.body.style.cursor = 'default'; }, didntReceivePage : function(response) { errorMessage('error loading page', response); $('sitetree').getTreeNodeByIdx(this.elements.ID.value).removeNodeClass('loading'); }, /** * Request a page from the server via Ajax */ getPageFromServer : function(id, treeNode) { // if(id && id.match(/^[A-Za-z0-9_]+$/)) { if(id && (id == 'root' || parseInt(id) == id || (id.substr && id.substr(0,3) == 'new') )) { this.receivingID = id; // Treenode might not exist if that part of the tree is closed if(!treeNode) treeNode = $('sitetree').getTreeNodeByIdx(id); if(treeNode) { $('sitetree').loadingNode = treeNode; treeNode.addNodeClass('loading'); url = treeNode.aTag.href + (treeNode.aTag.href.indexOf('?')==-1?'?':'&') + 'ajax=1'; } if(SiteTreeHandlers.loadPage_url) { var sep = (SiteTreeHandlers.loadPage_url.indexOf('?') == -1) ? '?' : '&'; url = SiteTreeHandlers.loadPage_url + sep + 'ID=' + id; } // used to set language in CMSMain->init() var lang = $('LangSelector') ? $F('LangSelector') : null; if(lang) { url += '&locale='+lang; } statusMessage("loading..."); this.loadURLFromServer(url); } else { throw("getPageFromServer: Bad page ID: " + id); } } /** * Set the status field */ /*setStatus: function(newStatus) { var statusLabel = document.getElementsBySelector('label.pageStatusMessage')[0]; if(statusLabel) statusLabel.innerHTML = "STATUS: " + newStatus; }*/ } CMSForm.applyTo('#Form_SubForm'); CMSRightForm.applyTo('#Form_EditForm', 'right'); function action_save_right() { _AJAX_LOADING = true; $('Form_EditForm_action_save').value = ss.i18n._t('CMSMAIN.SAVING'); $('Form_EditForm_action_save').className = 'action loading'; $('Form_EditForm_action_save').stopLoading = function() { if($('Form_EditForm_action_save') && $('Form_EditForm_action_save').className.indexOf('loading') != -1) { $('Form_EditForm_action_save').value = 'Save'; Element.removeClassName($('Form_EditForm_action_save'), 'loading'); } } $('Form_EditForm').save(false); } function action_save_siteconfig_right() { _AJAX_LOADING = true; if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave(); $('Form_EditForm_action_save_siteconfig').value = ss.i18n._t('CMSMAIN.SAVING'); $('Form_EditForm_action_save_siteconfig').className = 'action loading'; $('Form_EditForm').save(null, function() { if($('Form_EditForm_action_save_siteconfig') && $('Form_EditForm_action_save_siteconfig').className.indexOf('loading') != -1) { $('Form_EditForm_action_save_siteconfig').value = 'Save'; Element.removeClassName($('Form_EditForm_action_save_siteconfig'), 'loading'); } }, 'save_siteconfig'); } /** * Handle auto-saving. Detects if changes have been made, and if so save everything on the page. * If confirmation is true it will ask for confirmation. */ function autoSave(confirmation, callAfter) { // Note: TinyMCE coupling if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave(); var __forms = [] if($('Form_EditForm')) __forms.push($('Form_EditForm')); if($('Form_SubForm')) __forms.push($('Form_SubForm')); var __somethingHasChanged = false; var __callAfter = callAfter; __forms.each(function(form) { if(form.isChanged && form.isChanged()) { __somethingHasChanged = true; } }); if(__somethingHasChanged) { // Note: discard and cancel options are no longer used since switching to confirm dialog. // save is still used if confirmation = false var options = { save: function() { statusMessage(ss.i18n._t('CMSMAIN.SAVING'), '', true); var i; for(i=0;i<__forms.length;i++) { if(__forms[i].isChanged && __forms[i].isChanged()) { if(i == 0) __forms[i].save(true, __callAfter); else __forms[i].save(true); } } }, discard: function() { __forms.each(function(form) { form.resetElements(false); }); if(__callAfter) __callAfter(); }, cancel: function() { } } if(confirmation ) { if(confirm(ss.i18n._t('LeftAndMain.CONFIRMUNSAVED'))) { // OK was pressed, call function for what was clicked on if(__callAfter) __callAfter(); } else { // Cancel was pressed, stay on the current page return false; } } else { options.save(); } } else { if(__callAfter) __callAfter(); } } window.name = windowName('cms'); /** * Return a unique window name that contains the URL */ function windowName(suffix) { var base = document.getElementsByTagName('base')[0].href.replace('~','').replace('http://','').replace(/\//g,'_').replace(/\./g,'_'); return base + suffix; } /** * Remove all the currently active TinyMCE editors. * Note: everything that calls this has an inappropriate coupling to TinyMCE. * Perhaps an observer pattern could be used, where TinyMCE listens to a onBeforeCMSPageLoad * event? */ function tinymce_removeAll() { if((typeof tinymce != 'undefined') && tinymce.EditorManager) { var id; for(id in tinymce.EditorManager.editors) { tinymce.EditorManager.editors[id].remove(); } tinymce.EditorManager.editors = {}; } }