silverstripe-cms/javascript/LeftAndMain_right.js

447 lines
13 KiB
JavaScript
Raw Normal View History

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>&#160;</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) {
var rightHTML = formContent;
// reset the version view history
if($('versions_holder')) $('versions_holder').reset();
// 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(ss.i18n._t('LOADING', '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;
// Don't need to restore the button state after ajax success because the form is replaced completely
var btn = jQuery('#Form_EditForm_action_save');
btn.val(ss.i18n._t('CMSMAIN.SAVING')).addClass('loading').attr('disabled', 'disabled');
btn[0].stopLoading = function() {
btn.val('Save').removeClass('loading').removeAttr('disabled');
};
$('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 = {};
}
}