Merge branch 'MDL-64573-master' of git://github.com/damyon/moodle

This commit is contained in:
Jun Pataleta 2019-04-26 10:50:55 +08:00
commit cb7263feb0
16 changed files with 107 additions and 18 deletions

View File

@ -1 +1 @@
define(["jquery","core/event","core/str","core/notification","core/templates","core/custom_interaction_events","core/modal","core/modal_registry","core/fragment","core_calendar/events","core_calendar/repository"],function(a,b,c,d,e,f,g,h,i,j,k){var l=!1,m={SAVE_BUTTON:'[data-action="save"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]'},n=function(a){g.call(this,a),this.eventId=null,this.startTime=null,this.courseId=null,this.categoryId=null,this.contextId=null,this.reloadingBody=!1,this.reloadingTitle=!1,this.saveButton=this.getFooter().find(m.SAVE_BUTTON)};return n.TYPE="core_calendar-modal_event_form",n.prototype=Object.create(g.prototype),n.prototype.constructor=n,n.prototype.setContextId=function(a){this.contextId=a},n.prototype.getContextId=function(){return this.contextId},n.prototype.setCourseId=function(a){this.courseId=a},n.prototype.getCourseId=function(){return this.courseId},n.prototype.setCategoryId=function(a){this.categoryId=a},n.prototype.getCategoryId=function(){return this.categoryId},n.prototype.hasCourseId=function(){return null!==this.courseId},n.prototype.hasCategoryId=function(){return null!==this.categoryId},n.prototype.setEventId=function(a){this.eventId=a},n.prototype.getEventId=function(){return this.eventId},n.prototype.hasEventId=function(){return null!==this.eventId},n.prototype.setStartTime=function(a){this.startTime=a},n.prototype.getStartTime=function(){return this.startTime},n.prototype.hasStartTime=function(){return null!==this.startTime},n.prototype.getForm=function(){return this.getBody().find("form")},n.prototype.disableButtons=function(){this.saveButton.prop("disabled",!0)},n.prototype.enableButtons=function(){this.saveButton.prop("disabled",!1)},n.prototype.reloadTitleContent=function(){return this.reloadingTitle?this.titlePromise:(this.reloadingTitle=!0,this.hasEventId()?this.titlePromise=c.get_string("editevent","calendar"):this.titlePromise=c.get_string("newevent","calendar"),this.titlePromise.then(function(a){return this.setTitle(a),a}.bind(this)).always(function(){this.reloadingTitle=!1}.bind(this)).fail(d.exception),this.titlePromise)},n.prototype.reloadBodyContent=function(a){if(this.reloadingBody)return this.bodyPromise;this.reloadingBody=!0,this.disableButtons();var b={};return this.hasEventId()&&(b.eventid=this.getEventId()),this.hasStartTime()&&(b.starttime=this.getStartTime()),this.hasCourseId()&&(b.courseid=this.getCourseId()),this.hasCategoryId()&&(b.categoryid=this.getCategoryId()),"undefined"!=typeof a&&(b.formdata=a),this.bodyPromise=i.loadFragment("calendar","event_form",this.getContextId(),b),this.setBody(this.bodyPromise),this.bodyPromise.then(function(){this.enableButtons()}.bind(this)).fail(d.exception).always(function(){this.reloadingBody=!1}.bind(this)).fail(d.exception),this.bodyPromise},n.prototype.reloadAllContent=function(){return a.when(this.reloadTitleContent(),this.reloadBodyContent())},n.prototype.show=function(){this.reloadAllContent(),g.prototype.show.call(this)},n.prototype.hide=function(){g.prototype.hide.call(this),this.setEventId(null),this.setStartTime(null),this.setCourseId(null),this.setCategoryId(null)},n.prototype.getFormData=function(){return this.getForm().serialize()},n.prototype.save=function(){var b=this.saveButton.find(m.LOADING_ICON_CONTAINER);b.removeClass("hidden"),this.disableButtons();var c=this.getFormData();return k.submitCreateUpdateForm(c).then(function(b){if(b.validationerror)return void this.reloadBodyContent(c);var d=this.hasEventId();this.hide(),d?a("body").trigger(j.updated,[b.event]):a("body").trigger(j.created,[b.event])}.bind(this)).always(function(){b.addClass("hidden"),this.enableButtons()}.bind(this)).fail(d.exception)},n.prototype.registerEventListeners=function(){g.prototype.registerEventListeners.call(this),this.getModal().on(f.events.activate,m.SAVE_BUTTON,function(a,b){this.getForm().submit(),b.originalEvent.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on("submit",function(a){this.save(),a.preventDefault(),a.stopPropagation()}.bind(this))},l||(h.register(n.TYPE,n,"calendar/modal_event_form"),l=!0),n});
define(["jquery","core/event","core/str","core/notification","core/templates","core/custom_interaction_events","core/modal","core/modal_registry","core/fragment","core_calendar/events","core_calendar/repository"],function(a,b,c,d,e,f,g,h,i,j,k){var l=!1,m={SAVE_BUTTON:'[data-action="save"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]'},n=function(a){g.call(this,a),this.eventId=null,this.startTime=null,this.courseId=null,this.categoryId=null,this.contextId=null,this.reloadingBody=!1,this.reloadingTitle=!1,this.saveButton=this.getFooter().find(m.SAVE_BUTTON)};return n.TYPE="core_calendar-modal_event_form",n.prototype=Object.create(g.prototype),n.prototype.constructor=n,n.prototype.setContextId=function(a){this.contextId=a},n.prototype.getContextId=function(){return this.contextId},n.prototype.setCourseId=function(a){this.courseId=a},n.prototype.getCourseId=function(){return this.courseId},n.prototype.setCategoryId=function(a){this.categoryId=a},n.prototype.getCategoryId=function(){return this.categoryId},n.prototype.hasCourseId=function(){return null!==this.courseId},n.prototype.hasCategoryId=function(){return null!==this.categoryId},n.prototype.setEventId=function(a){this.eventId=a},n.prototype.getEventId=function(){return this.eventId},n.prototype.hasEventId=function(){return null!==this.eventId},n.prototype.setStartTime=function(a){this.startTime=a},n.prototype.getStartTime=function(){return this.startTime},n.prototype.hasStartTime=function(){return null!==this.startTime},n.prototype.getForm=function(){return this.getBody().find("form")},n.prototype.disableButtons=function(){this.saveButton.prop("disabled",!0)},n.prototype.enableButtons=function(){this.saveButton.prop("disabled",!1)},n.prototype.reloadTitleContent=function(){return this.reloadingTitle?this.titlePromise:(this.reloadingTitle=!0,this.hasEventId()?this.titlePromise=c.get_string("editevent","calendar"):this.titlePromise=c.get_string("newevent","calendar"),this.titlePromise.then(function(a){return this.setTitle(a),a}.bind(this)).always(function(){this.reloadingTitle=!1}.bind(this)).fail(d.exception),this.titlePromise)},n.prototype.reloadBodyContent=function(a){if(this.reloadingBody)return this.bodyPromise;this.reloadingBody=!0,this.disableButtons();var b={};return this.hasEventId()&&(b.eventid=this.getEventId()),this.hasStartTime()&&(b.starttime=this.getStartTime()),this.hasCourseId()&&(b.courseid=this.getCourseId()),this.hasCategoryId()&&(b.categoryid=this.getCategoryId()),"undefined"!=typeof a&&(b.formdata=a),this.bodyPromise=i.loadFragment("calendar","event_form",this.getContextId(),b),this.setBody(this.bodyPromise),this.bodyPromise.then(function(){this.enableButtons()}.bind(this)).fail(d.exception).always(function(){this.reloadingBody=!1}.bind(this)).fail(d.exception),this.bodyPromise},n.prototype.reloadAllContent=function(){return a.when(this.reloadTitleContent(),this.reloadBodyContent())},n.prototype.show=function(){this.reloadAllContent(),g.prototype.show.call(this)},n.prototype.hide=function(){g.prototype.hide.call(this),this.setEventId(null),this.setStartTime(null),this.setCourseId(null),this.setCategoryId(null)},n.prototype.getFormData=function(){return this.getForm().serialize()},n.prototype.save=function(){var b,c=this.saveButton.find(m.LOADING_ICON_CONTAINER);if(b=this.getForm().find('[aria-invalid="true"]'),b.length)return void b.first().focus();c.removeClass("hidden"),this.disableButtons();var e=this.getFormData();return k.submitCreateUpdateForm(e).then(function(b){if(b.validationerror)return void this.reloadBodyContent(e);var c=this.hasEventId();this.hide(),c?a("body").trigger(j.updated,[b.event]):a("body").trigger(j.created,[b.event])}.bind(this)).always(function(){c.addClass("hidden"),this.enableButtons()}.bind(this)).fail(d.exception)},n.prototype.registerEventListeners=function(){g.prototype.registerEventListeners.call(this),this.getModal().on(f.events.activate,m.SAVE_BUTTON,function(a,b){this.getForm().submit(),b.originalEvent.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on("submit",function(a){b.notifyFormSubmitAjax(this.getForm()[0]),this.save(),a.preventDefault(),a.stopPropagation()}.bind(this))},l||(h.register(n.TYPE,n,"calendar/modal_event_form"),l=!0),n});

View File

@ -407,7 +407,17 @@ define([
* @return {object} A promise
*/
ModalEventForm.prototype.save = function() {
var loadingContainer = this.saveButton.find(SELECTORS.LOADING_ICON_CONTAINER);
var invalid,
loadingContainer = this.saveButton.find(SELECTORS.LOADING_ICON_CONTAINER);
// Now the change events have run, see if there are any "invalid" form fields.
invalid = this.getForm().find('[aria-invalid="true"]');
// If we found invalid fields, focus on the first one and do not submit via ajax.
if (invalid.length) {
invalid.first().focus();
return;
}
loadingContainer.removeClass('hidden');
this.disableButtons();
@ -472,6 +482,8 @@ define([
// Catch the submit event before it is actually processed by the browser and
// prevent the submission. We'll take it from here.
this.getModal().on('submit', function(e) {
Event.notifyFormSubmitAjax(this.getForm()[0]);
this.save();
// Stop the form from actually submitting and prevent it's

View File

@ -1 +1 @@
define(["jquery","core/yui"],function(a,b){return{Events:{FORM_FIELD_VALIDATION:"core_form-field-validation"},getLegacyEvents:function(){var c=a.Deferred();return b.use("event","moodle-core-event",function(){c.resolve(window.M.core.event)}),c.promise()},notifyFilterContentUpdated:function(c){c=a(c),b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.FILTER_CONTENT_UPDATED,[c]);var d=new b.NodeList(c.get());b.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:d})})},notifyEditorContentRestored:function(){b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.EDITOR_CONTENT_RESTORED),b.fire(M.core.event.EDITOR_CONTENT_RESTORED)})}}});
define(["jquery","core/yui"],function(a,b){return{Events:{FORM_FIELD_VALIDATION:"core_form-field-validation"},getLegacyEvents:function(){var c=a.Deferred();return b.use("event","moodle-core-event",function(){c.resolve(window.M.core.event)}),c.promise()},notifyFilterContentUpdated:function(c){c=a(c),b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.FILTER_CONTENT_UPDATED,[c]);var d=new b.NodeList(c.get());b.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:d})})},notifyFormSubmitAjax:function(c,d){d=d||!1,b.use("event","moodle-core-event",function(b){d&&(window.skipClientValidation=!0),a(c).trigger(M.core.event.FORM_SUBMIT_AJAX),b.one(c).fire(M.core.event.FORM_SUBMIT_AJAX,{currentTarget:b.one(c)}),d&&(window.skipClientValidation=!1)})},notifyEditorContentRestored:function(){b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.EDITOR_CONTENT_RESTORED),b.fire(M.core.event.EDITOR_CONTENT_RESTORED)})}}});

View File

@ -68,6 +68,35 @@ define(['jquery', 'core/yui'],
Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: yuiNodes});
});
},
/**
* Trigger an event using both JQuery and YUI
*
* @method notifyFormSubmittedAjax
* @param {DOMElement} form
* @param {boolean} skipValidation Submit the form without validation. E.g. "Cancel".
*/
notifyFormSubmitAjax: function(form, skipValidation) {
// Argument is optional.
skipValidation = skipValidation || false;
Y.use('event', 'moodle-core-event', function(Y) {
if (skipValidation) {
window.skipClientValidation = true;
}
// Trigger it the JQuery way.
$(form).trigger(M.core.event.FORM_SUBMIT_AJAX);
// And again for YUI.
Y.one(form).fire(M.core.event.FORM_SUBMIT_AJAX, {currentTarget: Y.one(form)});
if (skipValidation) {
window.skipClientValidation = false;
}
});
},
/**
* Trigger an event using both JQuery and YUI
* This event alerts the world that the editor has restored some content.

View File

@ -1222,6 +1222,7 @@ Y.extend(EditorAutosaveIoDispatcher, Y.Base, {
if (typeof this._submitEvents[node.generateID()] === 'undefined') {
this._submitEvents[node.generateID()] = {
event: node.on('submit', this._onSubmit, this),
ajaxEvent: node.on(M.core.event.FORM_SUBMIT_AJAX, this._onSubmit, this),
ios: []
};
}

File diff suppressed because one or more lines are too long

View File

@ -1211,6 +1211,7 @@ Y.extend(EditorAutosaveIoDispatcher, Y.Base, {
if (typeof this._submitEvents[node.generateID()] === 'undefined') {
this._submitEvents[node.generateID()] = {
event: node.on('submit', this._onSubmit, this),
ajaxEvent: node.on(M.core.event.FORM_SUBMIT_AJAX, this._onSubmit, this),
ios: []
};
}

View File

@ -198,6 +198,7 @@ Y.extend(EditorAutosaveIoDispatcher, Y.Base, {
if (typeof this._submitEvents[node.generateID()] === 'undefined') {
this._submitEvents[node.generateID()] = {
event: node.on('submit', this._onSubmit, this),
ajaxEvent: node.on(M.core.event.FORM_SUBMIT_AJAX, this._onSubmit, this),
ios: []
};
}

View File

@ -66,6 +66,12 @@ M.editor_tinymce.init_editor = function(Y, editorid, options) {
editor.onChange.add(function(ed) {
ed.save();
});
Y.use('event', 'moodle-core-event', function(Y) {
var form = Y.one(document.getElementById(editor.id)).ancestor('form');
form.on(M.core.event.FORM_SUBMIT_AJAX, function() {
editor.save();
}, this)
});
};
tinyMCE.init(options);

View File

@ -2421,6 +2421,17 @@ require(["core/event", "jquery"], function(Event, $) {
return ret;
}
var form = $(document.getElementById(\'' . $this->_attributes['id'] . '\')).closest(\'form\');
form.on(M.core.event.FORM_SUBMIT_AJAX, function() {
try {
var myValidator = validate_' . $this->_formName . ';
} catch(e) {
return true;
}
if (myValidator) {
myValidator();
}
});
document.getElementById(\'' . $this->_attributes['id'] . '\').addEventListener(\'submit\', function(ev) {
try {

View File

@ -31,6 +31,7 @@ var LOGNAME = 'moodle-core-event';
M.core = M.core || {};
M.core.event = M.core.event || {
/**
* This event is triggered when a page has added dynamic nodes to a page
* that should be processed by the filter system. An example is loading
@ -42,6 +43,7 @@ M.core.event = M.core.event || {
* @param nodes {Y.NodeList} List of nodes added to the DOM.
*/
FILTER_CONTENT_UPDATED: "filter-content-updated",
/**
* This event is triggered when an editor has recovered some draft text.
* It can be used to determine let other sections know that they should reset their
@ -49,7 +51,15 @@ M.core.event = M.core.event || {
*
* @event "editor-content-restored"
*/
EDITOR_CONTENT_RESTORED: "editor-content-restored"
EDITOR_CONTENT_RESTORED: "editor-content-restored",
/**
* This event is triggered when an mform is about to be submitted via ajax.
*
* @event "form-submit-ajax"
*/
FORM_SUBMIT_AJAX: "form-submit-ajax"
};
M.core.globalEvents = M.core.globalEvents || {

View File

@ -1 +1 @@
YUI.add("moodle-core-event",function(e,t){var n="moodle-core-event";M.core=M.core||{},M.core.event=M.core.event||{FILTER_CONTENT_UPDATED:"filter-content-updated",EDITOR_CONTENT_RESTORED:"editor-content-restored"},M.core.globalEvents=M.core.globalEvents||{FORM_ERROR:"form_error",BLOCK_CONTENT_UPDATED:"block_content_updated"};var r={emitFacade:!0,defaultFn:function(e){},preventedFn:function(e){},stoppedFn:function(e){}},i;for(i in M.core.event)M.core.event.hasOwnProperty(i)&&e.getEvent(M.core.event[i])===null&&e.publish(M.core.event[i],r);for(i in M.core.globalEvents)M.core.globalEvents.hasOwnProperty(i)&&e.Global.getEvent(M.core.globalEvents[i])===null&&e.Global.publish(M.core.globalEvents[i],e.merge(r,{broadcast:!0}))},"@VERSION@",{requires:["event-custom"]});
YUI.add("moodle-core-event",function(e,t){var n="moodle-core-event";M.core=M.core||{},M.core.event=M.core.event||{FILTER_CONTENT_UPDATED:"filter-content-updated",EDITOR_CONTENT_RESTORED:"editor-content-restored",FORM_SUBMIT_AJAX:"form-submit-ajax"},M.core.globalEvents=M.core.globalEvents||{FORM_ERROR:"form_error",BLOCK_CONTENT_UPDATED:"block_content_updated"};var r={emitFacade:!0,defaultFn:function(e){},preventedFn:function(e){},stoppedFn:function(e){}},i;for(i in M.core.event)M.core.event.hasOwnProperty(i)&&e.getEvent(M.core.event[i])===null&&e.publish(M.core.event[i],r);for(i in M.core.globalEvents)M.core.globalEvents.hasOwnProperty(i)&&e.Global.getEvent(M.core.globalEvents[i])===null&&e.Global.publish(M.core.globalEvents[i],e.merge(r,{broadcast:!0}))},"@VERSION@",{requires:["event-custom"]});

View File

@ -31,6 +31,7 @@ var LOGNAME = 'moodle-core-event';
M.core = M.core || {};
M.core.event = M.core.event || {
/**
* This event is triggered when a page has added dynamic nodes to a page
* that should be processed by the filter system. An example is loading
@ -42,6 +43,7 @@ M.core.event = M.core.event || {
* @param nodes {Y.NodeList} List of nodes added to the DOM.
*/
FILTER_CONTENT_UPDATED: "filter-content-updated",
/**
* This event is triggered when an editor has recovered some draft text.
* It can be used to determine let other sections know that they should reset their
@ -49,7 +51,15 @@ M.core.event = M.core.event || {
*
* @event "editor-content-restored"
*/
EDITOR_CONTENT_RESTORED: "editor-content-restored"
EDITOR_CONTENT_RESTORED: "editor-content-restored",
/**
* This event is triggered when an mform is about to be submitted via ajax.
*
* @event "form-submit-ajax"
*/
FORM_SUBMIT_AJAX: "form-submit-ajax"
};
M.core.globalEvents = M.core.globalEvents || {

View File

@ -29,6 +29,7 @@ var LOGNAME = 'moodle-core-event';
M.core = M.core || {};
M.core.event = M.core.event || {
/**
* This event is triggered when a page has added dynamic nodes to a page
* that should be processed by the filter system. An example is loading
@ -40,6 +41,7 @@ M.core.event = M.core.event || {
* @param nodes {Y.NodeList} List of nodes added to the DOM.
*/
FILTER_CONTENT_UPDATED: "filter-content-updated",
/**
* This event is triggered when an editor has recovered some draft text.
* It can be used to determine let other sections know that they should reset their
@ -47,7 +49,15 @@ M.core.event = M.core.event || {
*
* @event "editor-content-restored"
*/
EDITOR_CONTENT_RESTORED: "editor-content-restored"
EDITOR_CONTENT_RESTORED: "editor-content-restored",
/**
* This event is triggered when an mform is about to be submitted via ajax.
*
* @event "form-submit-ajax"
*/
FORM_SUBMIT_AJAX: "form-submit-ajax"
};
M.core.globalEvents = M.core.globalEvents || {

File diff suppressed because one or more lines are too long

View File

@ -25,8 +25,8 @@
*/
define(['jquery', 'core/yui', 'core/notification', 'core/templates', 'core/fragment',
'core/ajax', 'core/str', 'mod_assign/grading_form_change_checker',
'mod_assign/grading_events'],
function($, Y, notification, templates, fragment, ajax, str, checker, GradingEvents) {
'mod_assign/grading_events', 'core/event'],
function($, Y, notification, templates, fragment, ajax, str, checker, GradingEvents, Event) {
/**
* GradingPanel class.
@ -89,11 +89,6 @@ define(['jquery', 'core/yui', 'core/notification', 'core/templates', 'core/fragm
* @method _saveFormState
*/
GradingPanel.prototype._saveFormState = function() {
// Grrrrr! TinyMCE you know what you did.
if (typeof window.tinyMCE !== 'undefined') {
window.tinyMCE.triggerSave();
}
// Copy data from notify students checkbox which was moved out of the form.
var checked = $('[data-region="grading-actions-form"] [name="sendstudentnotifications"]').prop("checked");
$('.gradeform [name="sendstudentnotifications"]').val(checked);
@ -117,6 +112,9 @@ define(['jquery', 'core/yui', 'core/notification', 'core/templates', 'core/fragm
// We call this, so other modules can update the form with the latest state.
form.trigger('save-form-state');
// Tell all form fields we are about to submit the form.
Event.notifyFormSubmitAjax(form[0]);
// Now we get all the current values from the form.
var data = form.serialize();
var assignmentid = this._region.attr('data-assignmentid');