diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 405b91b1..c5aeaebd 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -214,6 +214,7 @@ class LeftAndMain extends Controller { Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-livequery/jquery.livequery.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-cookie/jquery.cookie.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js'); + Requirements::javascript(CMS_DIR . '/javascript/jquery-changetracker/lib/jquery.changetracker.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/prototype_improvements.js'); Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang'); Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang'); @@ -227,7 +228,6 @@ class LeftAndMain extends Controller { Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_left.js'); - Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_right.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.EditForm.js'); Requirements::javascript(CMS_DIR . '/javascript/SideTabs.js'); diff --git a/javascript/CMSMain.js b/javascript/CMSMain.js index d10653ce..2caa41b1 100644 --- a/javascript/CMSMain.js +++ b/javascript/CMSMain.js @@ -124,6 +124,7 @@ var ss_MainLayout; */ $('#Form_EditForm').concrete('ss', function($){ return/** @lends ss.EditForm */{ + /* onmatch: function() { // Alert the user on change of page-type - this might have implications // on the available form fields etc. @@ -132,7 +133,10 @@ var ss_MainLayout; alert('The page type will be updated after the page is saved'); } ); + + $._super(); } + */ }; }); diff --git a/javascript/CMSMain_left.js b/javascript/CMSMain_left.js index 8175094d..f91f2bf7 100755 --- a/javascript/CMSMain_left.js +++ b/javascript/CMSMain_left.js @@ -436,11 +436,11 @@ TreeContextMenu = { }, 'Duplicate page and children' : function(treeNode) { // First save the page silently (without confirmation) and then duplicate the page. - autoSave(false, treeNode.duplicatePageWithChildren.bind(treeNode)); + jQuery('#Form_EditForm').concrete('ss').ajaxSubmit(null, treeNode.duplicatePageWithChildren.bind(treeNode)); }, 'Duplicate just this page' : function(treeNode) { // First save the page silently (without confirmation) and then duplicate the page. - autoSave(false, treeNode.duplicatePage.bind(treeNode)); + jQuery('#Form_EditForm').concrete('ss').ajaxSubmit(null, treeNode.duplicatePageWithChildren.bind(treeNode)); }, 'Sort sub-pages' : function(treeNode) { var children = treeNode.treeNodeHolder().childTreeNodes(); diff --git a/javascript/LeftAndMain.EditForm.js b/javascript/LeftAndMain.EditForm.js index 9b758ce7..6d894d4c 100644 --- a/javascript/LeftAndMain.EditForm.js +++ b/javascript/LeftAndMain.EditForm.js @@ -5,6 +5,7 @@ * and reloading itself through the ajax return values. * Takes care of resizing tabsets within the layout container. * @name ss.Form_EditForm + * @require jquery.changetracker */ $('#Form_EditForm').concrete('ss',function($){ return/** @lends ss.Form_EditForm */{ @@ -15,11 +16,44 @@ */ RemoveText: 'Removed', + /** + * @type Object + */ + ChangeTrackerOptions: {}, + onmatch: function() { + this._setupChangeTracker(); + + $._super(); + }, + + _setupChangeTracker: function() { + var self = this; + // Don't bind any events here, as we dont replace the // full
tag by any ajax updates they won't automatically reapply + this.changetracker(this.ChangeTrackerOptions()); - _super(); + var autoSaveOnUnload = function(e) { + // @todo TinyMCE coupling + if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave(); + if(self.is('.changed') && confirm(ss.i18n._t('LeftAndMain.CONFIRMUNSAVED'))) { + // unloads can't be prevented, but we can delay it with a synchronous ajax request + self.ajaxSubmit( + self.find(':submit[name=action_save]'), + null, + {async: false} + ); + } + }; + + // use custom IE 'onbeforeunload' event, as it destroys the DOM + // before going into 'unload' + if(typeof window.onbeforeunload != 'undefined') { + window.onbeforeunload = autoSaveOnUnload; + } else { + $(window).unload(autoSaveOnUnload); + } }, /** diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 51eae703..be8e828a 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -293,25 +293,6 @@ var _AJAX_LOADING = false; -Behaviour.register({ - - '#MainMenu li' : { - onclick : function(event) { - LeftAndMain_window_unload(); // Confirm if there are unsaved changes - window.location.href = this.getElementsByTagName('a')[0].href; - Event.stop(event); - } - } - -}); - - -LeftAndMain_window_unload = function() { - window.exiting = true; // this is used by prototype - if(typeof autoSave == 'function') { - return autoSave(true); - } -} // Event.observe(window, 'beforeunload', LeftAndMain_window_unload); @@ -498,105 +479,6 @@ StatusTitle.prototype = { } */ - -/** - * ChangeTracker is a class that can be applied to forms to support change tracking on forms. - */ -ChangeTracker = Class.create(); -ChangeTracker.prototype = { - initialize: function() { - this.resetElements(); - }, - - /** - * Reset all the 'changed field' data. - */ - resetElements: function(debug) { - var elements = Form.getElements(this); - var i, element; - for(i=0;element=elements[i];i++) { - // Initialise each element - if(element.resetChanged) { - element.resetChanged(); - } else { - element.originalSerialized = Form.Element.serialize(element); - } - } - }, - - field_changed: function() { - // Something a value will go from 'undefined' to ''. Ignore such changes - if((this.originalSerialized+'') == 'undefined') return Form.Element.serialize(this) ? true : false; - else return this.originalSerialized != Form.Element.serialize(this); - }, - - /** - * Returns true if something in the form has been changed - */ - isChanged: function() { - var elements = Form.getElements(this); - var i, element; - for(i=0;element=elements[i];i++) { - // NOTE: TinyMCE coupling - // Ignore mce-generated elements - if(element.className.substr(0,3) == 'mce') continue; - - if(!element.isChanged) element.isChanged = this.field_changed; - if(!this.changeDetection_fieldsToIgnore[element.name] && element.isChanged()) { - //console.log('Changed:'+ element.id + '(' + this.originalSerialized +')->('+Form.Element.serialize(element)+')' ); - //console.log(element) - - return true; - } - } - return false; - }, - - changeDetection_fieldsToIgnore : { - 'Sort' : true - }, - - /** - * Serialize only the fields to change. - * You can specify the names of fields that must be included as arguments - */ - serializeChangedFields: function() { - var elements = Form.getElements(this); - var queryComponent, queryComponents = new Array(); - var i, element; - - var forceFields = {}; - if(arguments) {for(var i=0;i