From dfd0021749949ab835b76e8d1b6f8628825784d6 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 10 May 2019 10:47:44 +0800 Subject: [PATCH] MDL-65469 core: Expose formchecker to initialize current form state --- lib/formslib.php | 40 ++++++++++++++++++- .../moodle-core-formchangechecker-debug.js | 7 ++++ .../moodle-core-formchangechecker-min.js | 2 +- .../moodle-core-formchangechecker.js | 7 ++++ .../formchangechecker/js/formchangechecker.js | 7 ++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/formslib.php b/lib/formslib.php index bc0d5812326..ca39e81c47a 100644 --- a/lib/formslib.php +++ b/lib/formslib.php @@ -1448,6 +1448,16 @@ abstract class moodleform { $oldclass = $this->_form->getAttribute('class'); $this->_form->updateAttributes(array('class' => $oldclass . ' full-width-labels')); } + + /** + * Set the initial 'dirty' state of the form. + * + * @param bool $state + * @since Moodle 3.7.1 + */ + public function set_initial_dirty_state($state = false) { + $this->_form->set_initial_dirty_state($state); + } } /** @@ -1503,6 +1513,13 @@ class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless { /** @var bool whether to automatically initialise M.formchangechecker for this form. */ protected $_use_form_change_checker = true; + /** + * The initial state of the dirty state. + * + * @var bool + */ + protected $_initial_form_dirty_state = false; + /** * The form name is derived from the class name of the wrapper minus the trailing form * It is a name with words joined by underscores whereas the id attribute is words joined by underscores. @@ -1721,6 +1738,26 @@ class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless { $this->_disableShortforms = $disable; } + /** + * Set the initial 'dirty' state of the form. + * + * @param bool $state + * @since Moodle 3.7.1 + */ + public function set_initial_dirty_state($state = false) { + $this->_initial_form_dirty_state = $state; + } + + /** + * Is the form currently set to dirty? + * + * @return boolean Initial dirty state. + * @since Moodle 3.7.1 + */ + public function is_dirty() { + return $this->_initial_form_dirty_state; + } + /** * Call this method if you don't want the formchangechecker JavaScript to be * automatically initialised for this form. @@ -2964,7 +3001,8 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{ $PAGE->requires->yui_module('moodle-core-formchangechecker', 'M.core_formchangechecker.init', array(array( - 'formid' => $formid + 'formid' => $formid, + 'initialdirtystate' => $form->is_dirty(), )) ); $PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle'); diff --git a/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-debug.js b/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-debug.js index b584c620f47..cd394077e0a 100644 --- a/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-debug.js +++ b/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-debug.js @@ -38,6 +38,10 @@ Y.extend(FORMCHANGECHECKER, Y.Base, { return; } + if (!M.core_formchangechecker.stateinformation.formchanged) { + M.core_formchangechecker.stateinformation.formchanged = this.get('initialdirtystate'); + } + // Add a listener here for an editor restore event. Y.on(M.core.event.EDITOR_CONTENT_RESTORED, M.core_formchangechecker.reset_form_dirty_state, this); @@ -98,6 +102,9 @@ Y.extend(FORMCHANGECHECKER, Y.Base, { ATTRS: { formid: { 'value': '' + }, + initialdirtystate: { + 'value': false } } } diff --git a/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-min.js b/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-min.js index 81f74b4dc0f..9eb3b20d521 100644 --- a/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-min.js +++ b/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-min.js @@ -1 +1 @@ -YUI.add("moodle-core-formchangechecker",function(e,t){var n="core-formchangechecker",r=function(){r.superclass.constructor.apply(this,arguments)};e.extend(r,e.Base,{initialvaluelisteners:[],initializer:function(){var t="form#"+this.get("formid"),n=e.one(t);if(!n)return;e.on(M.core.event.EDITOR_CONTENT_RESTORED,M.core_formchangechecker.reset_form_dirty_state,this),n.delegate("change",M.core_formchangechecker.set_form_changed,"input",this),n.delegate("change",M.core_formchangechecker.set_form_changed,"textarea",this),n.delegate("change",M.core_formchangechecker.set_form_changed,"select",this),this.initialvaluelisteners.push(n.delegate("focus",this.store_initial_value,"input",this)),this.initialvaluelisteners.push(n.delegate("focus",this.store_initial_value,"textarea",this)),this.initialvaluelisteners.push(n.delegate("focus",this.store_initial_value,"select",this)),e.one(t).on("submit",M.core_formchangechecker.set_form_submitted,this),window.onbeforeunload=M.core_formchangechecker.report_form_dirty_state},store_initial_value:function(e){var t;if(e.target.hasClass("ignoredirty")||e.target.ancestor(".ignoredirty"))return;if(M.core_formchangechecker.get_form_dirty_state()){while(this.initialvaluelisteners.length)t=this.initialvaluelisteners.shift(),t.detach();return}M.core_formchangechecker.stateinformation.focused_element={element:e.target,initial_value:e.target.get("value")}}},{NAME:n,ATTRS:{formid:{value:""}}}),M.core_formchangechecker=M.core_formchangechecker||{},M.core_formchangechecker.instances=M.core_formchangechecker.instances||[],M.core_formchangechecker.init=function(e){var t=new r(e);return M.core_formchangechecker.instances.push(t),t},M.core_formchangechecker.stateinformation=[],M.core_formchangechecker.set_form_changed=function(e){if(e&&e.target&&(e.target.hasClass("ignoredirty")||e.target.ancestor(".ignoredirty")))return;M.core_formchangechecker.stateinformation.formchanged=1,delete M.core_formchangechecker.stateinformation.focused_element},M.core_formchangechecker.set_form_submitted=function(){M.core_formchangechecker.stateinformation.formsubmitted=1},M.core_formchangechecker.get_form_dirty_state=function(){var e=M.core_formchangechecker.stateinformation,t;if(e.formsubmitted)return 0;if(e.formchanged)return 1;if(e.focused_element&&e.focused_element.element.get("value")!==e.focused_element.initial_value)return 1;if(typeof window.tinyMCE!="undefined")for(t in window.tinyMCE.editors)if(window.tinyMCE.editors[t].isDirty())return 1;return 0},M.core_formchangechecker.reset_form_dirty_state=function(){M.core_formchangechecker.stateinformation.formsubmitted=!1,M.core_formchangechecker.stateinformation.formchanged=!1},M.core_formchangechecker.report_form_dirty_state=function(e){if(!M.core_formchangechecker.get_form_dirty_state())return;var t=M.util.get_string("changesmadereallygoaway","moodle");if(M.cfg.behatsiterunning)return;return e&&(e.returnValue=t),t}},"@VERSION@",{requires:["base","event-focus","moodle-core-event"]}); +YUI.add("moodle-core-formchangechecker",function(e,t){var n="core-formchangechecker",r=function(){r.superclass.constructor.apply(this,arguments)};e.extend(r,e.Base,{initialvaluelisteners:[],initializer:function(){var t="form#"+this.get("formid"),n=e.one(t);if(!n)return;M.core_formchangechecker.stateinformation.formchanged||(M.core_formchangechecker.stateinformation.formchanged=this.get("initialdirtystate")),e.on(M.core.event.EDITOR_CONTENT_RESTORED,M.core_formchangechecker.reset_form_dirty_state,this),n.delegate("change",M.core_formchangechecker.set_form_changed,"input",this),n.delegate("change",M.core_formchangechecker.set_form_changed,"textarea",this),n.delegate("change",M.core_formchangechecker.set_form_changed,"select",this),this.initialvaluelisteners.push(n.delegate("focus",this.store_initial_value,"input",this)),this.initialvaluelisteners.push(n.delegate("focus",this.store_initial_value,"textarea",this)),this.initialvaluelisteners.push(n.delegate("focus",this.store_initial_value,"select",this)),e.one(t).on("submit",M.core_formchangechecker.set_form_submitted,this),window.onbeforeunload=M.core_formchangechecker.report_form_dirty_state},store_initial_value:function(e){var t;if(e.target.hasClass("ignoredirty")||e.target.ancestor(".ignoredirty"))return;if(M.core_formchangechecker.get_form_dirty_state()){while(this.initialvaluelisteners.length)t=this.initialvaluelisteners.shift(),t.detach();return}M.core_formchangechecker.stateinformation.focused_element={element:e.target,initial_value:e.target.get("value")}}},{NAME:n,ATTRS:{formid:{value:""},initialdirtystate:{value:!1}}}),M.core_formchangechecker=M.core_formchangechecker||{},M.core_formchangechecker.instances=M.core_formchangechecker.instances||[],M.core_formchangechecker.init=function(e){var t=new r(e);return M.core_formchangechecker.instances.push(t),t},M.core_formchangechecker.stateinformation=[],M.core_formchangechecker.set_form_changed=function(e){if(e&&e.target&&(e.target.hasClass("ignoredirty")||e.target.ancestor(".ignoredirty")))return;M.core_formchangechecker.stateinformation.formchanged=1,delete M.core_formchangechecker.stateinformation.focused_element},M.core_formchangechecker.set_form_submitted=function(){M.core_formchangechecker.stateinformation.formsubmitted=1},M.core_formchangechecker.get_form_dirty_state=function(){var e=M.core_formchangechecker.stateinformation,t;if(e.formsubmitted)return 0;if(e.formchanged)return 1;if(e.focused_element&&e.focused_element.element.get("value")!==e.focused_element.initial_value)return 1;if(typeof window.tinyMCE!="undefined")for(t in window.tinyMCE.editors)if(window.tinyMCE.editors[t].isDirty())return 1;return 0},M.core_formchangechecker.reset_form_dirty_state=function(){M.core_formchangechecker.stateinformation.formsubmitted=!1,M.core_formchangechecker.stateinformation.formchanged=!1},M.core_formchangechecker.report_form_dirty_state=function(e){if(!M.core_formchangechecker.get_form_dirty_state())return;var t=M.util.get_string("changesmadereallygoaway","moodle");if(M.cfg.behatsiterunning)return;return e&&(e.returnValue=t),t}},"@VERSION@",{requires:["base","event-focus","moodle-core-event"]}); diff --git a/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker.js b/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker.js index b584c620f47..cd394077e0a 100644 --- a/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker.js +++ b/lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker.js @@ -38,6 +38,10 @@ Y.extend(FORMCHANGECHECKER, Y.Base, { return; } + if (!M.core_formchangechecker.stateinformation.formchanged) { + M.core_formchangechecker.stateinformation.formchanged = this.get('initialdirtystate'); + } + // Add a listener here for an editor restore event. Y.on(M.core.event.EDITOR_CONTENT_RESTORED, M.core_formchangechecker.reset_form_dirty_state, this); @@ -98,6 +102,9 @@ Y.extend(FORMCHANGECHECKER, Y.Base, { ATTRS: { formid: { 'value': '' + }, + initialdirtystate: { + 'value': false } } } diff --git a/lib/yui/src/formchangechecker/js/formchangechecker.js b/lib/yui/src/formchangechecker/js/formchangechecker.js index f4545f4eeca..59d3283e03c 100644 --- a/lib/yui/src/formchangechecker/js/formchangechecker.js +++ b/lib/yui/src/formchangechecker/js/formchangechecker.js @@ -36,6 +36,10 @@ Y.extend(FORMCHANGECHECKER, Y.Base, { return; } + if (!M.core_formchangechecker.stateinformation.formchanged) { + M.core_formchangechecker.stateinformation.formchanged = this.get('initialdirtystate'); + } + // Add a listener here for an editor restore event. Y.on(M.core.event.EDITOR_CONTENT_RESTORED, M.core_formchangechecker.reset_form_dirty_state, this); @@ -96,6 +100,9 @@ Y.extend(FORMCHANGECHECKER, Y.Base, { ATTRS: { formid: { 'value': '' + }, + initialdirtystate: { + 'value': false } } }