From 5aef49a0a769ef931687f05bc4f6f687717f4878 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 21 Nov 2009 03:14:08 +0000 Subject: [PATCH] API CHANGE Removed ChangeTracker javascript class, superseded by jquery.changetracker API CHANGE Removed autoSave() javascript logic in CMS, superseded by custom code in LeftAndMain.EditForm.js ENHANCEMENT Using jquery.changetracker in LeftAndMain.EditForm.js, and overhauled window.unload logic to automatically trigger ajax saving after a user confirmation MINOR Changed unload confirmation text in CMS logic to adapt to new behaviour git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92685 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 2 +- javascript/CMSMain.js | 4 + javascript/CMSMain_left.js | 4 +- javascript/LeftAndMain.EditForm.js | 36 ++++++++- javascript/LeftAndMain.js | 118 ----------------------------- javascript/LeftAndMain_left.js | 2 +- javascript/LeftAndMain_right.js | 61 --------------- javascript/lang/en_US.js | 2 +- 8 files changed, 44 insertions(+), 185 deletions(-) delete mode 100755 javascript/LeftAndMain_right.js 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