MDL-31315 Ask before moving away from a modified form

This commit is contained in:
Andrew Robert Nicols 2012-01-23 11:36:53 +00:00
parent 216f6d8e9d
commit 00e8d08dba
6 changed files with 149 additions and 3 deletions

View File

@ -131,6 +131,12 @@ if (empty($SITE->fullname)) {
echo '</form>';
}
$PAGE->requires->yui_module('moodle-core-formslib',
'M.core.init_formslib',
array(array(
'formid' => 'adminsettings'
))
);
$PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle');
echo $OUTPUT->footer();

View File

@ -219,6 +219,7 @@ $string['categoryname'] = 'Category name';
$string['idnumbercoursecategory'] = 'Category ID number';
$string['idnumbercoursecategory_help'] = 'The ID number of a course category is only used when matching the category against external systems and is not displayed anywhere on the site. If the category has an official code name it may be entered, otherwise the field can be left blank.';
$string['categoryupdated'] = 'The category \'{$a}\' was updated';
$string['changesmadereallygoaway'] = 'You have made changes. Are you sure you want to navigate away and lose your changes?';
$string['city'] = 'City/town';
$string['clambroken'] = 'Your administrator has enabled virus checking for file uploads but has misconfigured something.<br />Your file upload was NOT successful. Your administrator has been emailed to notify them so they can fix it.<br />Maybe try uploading this file later.';
$string['clamdeletedfile'] = 'The file has been deleted';

View File

@ -144,6 +144,7 @@ M.form_filemanager.init = function(Y, options) {
this.filecount++;
this.check_buttons();
this.refresh(this.currentpath);
M.util.set_form_changed();
},
check_buttons: function() {
var button_addfile = Y.one("#btnadd-"+this.client_id);
@ -213,6 +214,7 @@ M.form_filemanager.init = function(Y, options) {
scope.mkdir_dialog.hide();
scope.refresh(filepath);
Y.one('#fm-newname').set('value', '');
M.util.set_form_changed();
}
});
}
@ -559,6 +561,7 @@ M.form_filemanager.init = function(Y, options) {
callback: function(id, obj, args) {
scope.filecount--;
scope.refresh(obj.filepath);
M.util.set_form_changed();
if (scope.filecount < scope.maxfiles && scope.maxfiles!=-1) {
var button_addfile = Y.one("#btnadd-"+scope.client_id);
button_addfile.setStyle('display', 'inline');
@ -606,6 +609,7 @@ M.form_filemanager.init = function(Y, options) {
alert(M.str.repository.fileexists);
} else {
scope.refresh(obj.filepath);
M.util.set_form_changed();
}
Y.one('#fm-rename-input').set('value', '');
scope.rename_dialog.hide();
@ -683,6 +687,7 @@ M.form_filemanager.init = function(Y, options) {
}
dialog.cancel();
scope.refresh(p);
M.util.set_form_changed();
}
});
}

View File

@ -2255,6 +2255,7 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
* @param object $form MoodleQuickForm
*/
function startForm(&$form){
global $PAGE;
$this->_reqHTML = $form->getReqHTML();
$this->_elementTemplates = str_replace('{req}', $this->_reqHTML, $this->_elementTemplates);
$this->_advancedHTML = $form->getAdvancedHTML();
@ -2267,7 +2268,13 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
$this->_hiddenHtml .= $form->_pageparams;
}
$PAGE->requires->yui_module('moodle-core-formslib',
'M.core.init_formslib',
array(array(
'formid' => $form->getAttribute('id')
))
);
$PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle');
}
/**

View File

@ -1752,4 +1752,72 @@ M.util.load_flowplayer = function() {
fileref.onreadystatechange = embed_function;
document.getElementsByTagName('head')[0].appendChild(fileref);
}
};
/**
* Set the form changed state to true
*/
M.util.set_form_changed = function() {
M.cfg.form_changed = 1;
};
/**
* Set the form submitted state to true
*/
M.util.set_form_submitted = function() {
M.cfg.form_submitted = 1;
}
/**
* Attempt to determine whether the form has been modified in any way and
* is thus 'dirty'
*
* @return Integer 1 is the form is dirty; 0 if not
*/
M.util.get_form_dirty_state = function() {
// If the form was submitted, then return a non-dirty state
if (M.cfg.form_submitted) {
return 0;
}
// If any fields have been marked dirty, return a dirty state
if (M.cfg.form_changed) {
return 1;
}
// Handle TinyMCE editor instances
// We can't add a listener in the initializer as the editors may not have been created by that point
// so we do so here instead
if (typeof tinyMCE != 'undefined') {
for (var editor in tinyMCE.editors) {
if (tinyMCE.editors[editor].isDirty()) {
return 1;
}
}
}
// If we reached here, then the form hasn't met any of the dirty conditions
return 0;
};
/**
* Return a suitable message if changes have been made to a form
*/
M.util.report_form_dirty_state = function(e) {
if (!M.util.get_form_dirty_state()) {
// the form is not dirty, so don't display any message
return;
}
// This is the error message that we'll show to browsers which support it
var returnValue = M.util.get_string('changesmadereallygoaway', 'moodle');
// Most browsers are happy with the returnValue being set on the event
// But some browsers do not consistently pass the event
if (e) {
e.returnValue = returnValue;
}
// But some require it to be returned instead
return returnValue;
};

59
lib/yui/formslib/formslib.js vendored Normal file
View File

@ -0,0 +1,59 @@
YUI.add('moodle-core-formslib',
function(Y) {
// The CSS selectors we use
var CSS = {
};
var FORMSLIBNAME = 'core-formslib';
var FORMSLIB = function() {
FORMSLIB.superclass.constructor.apply(this, arguments);
}
Y.extend(FORMSLIB, Y.Base, {
/**
* Initialize the module
*/
initializer : function(config) {
var formid = 'form#' + this.get('formid');
// Add change events to the form elements
Y.all(formid + ' input').on('change', M.util.set_form_changed, this);
Y.all(formid + ' textarea').on('change', M.util.set_form_changed, this);
Y.all(formid + ' select').on('change', M.util.set_form_changed, this);
// We need any submit buttons on the form to set the submitted flag
Y.one(formid).on('submit', M.util.set_form_submitted, this);
// YUI doesn't support onbeforeunload properly so we must use the DOM to set the onbeforeunload. As
// a result, the has_changed must stay in the DOM too
window.onbeforeunload = M.util.report_form_dirty_state;
},
/**
* Unset the form dirty state and also set the form submitted flag to true
*/
unset_changed : function(e) {
M.util.set_form_changed();
}
},
{
NAME : FORMSLIBNAME,
ATTRS : {
formid : {
'value' : ''
}
}
}
);
M.core = M.core || {};
M.core.init_formslib = function(config) {
return new FORMSLIB(config);
}
},
'@VERSION@', {
requires : ['base']
}
);