Skip to content

Commit

Permalink
MDL-31315 Ask before moving away from a modified form
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Robert Nicols committed Feb 9, 2012
1 parent 216f6d8 commit 00e8d08
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 3 deletions.
10 changes: 8 additions & 2 deletions admin/settings.php
Expand Up @@ -131,6 +131,12 @@
echo '</form>';
}

echo $OUTPUT->footer();

$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();
1 change: 1 addition & 0 deletions lang/en/moodle.php
Expand Up @@ -219,6 +219,7 @@
$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';
Expand Down
5 changes: 5 additions & 0 deletions lib/form/filemanager.js
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}
});
}
Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -683,6 +687,7 @@ M.form_filemanager.init = function(Y, options) {
}
dialog.cancel();
scope.refresh(p);
M.util.set_form_changed();
}
});
}
Expand Down
9 changes: 8 additions & 1 deletion lib/formslib.php
Expand Up @@ -2255,6 +2255,7 @@ function setAdvancedElements($elements){
* @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();
Expand All @@ -2267,7 +2268,13 @@ function startForm(&$form){
$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');
}

/**
Expand Down
68 changes: 68 additions & 0 deletions lib/javascript-static.js
Expand Up @@ -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 changes: 59 additions & 0 deletions lib/yui/formslib/formslib.js
@@ -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']
}
);

0 comments on commit 00e8d08

Please sign in to comment.