Skip to content

Commit

Permalink
MDL-59369 user: User enrolment status JS controls
Browse files Browse the repository at this point in the history
* Add actions for editing user enrolment and unenrol
* Render user enrolment details in a modal
  • Loading branch information
junpataleta committed Jul 26, 2017
1 parent fd0a43b commit 80d13bf
Show file tree
Hide file tree
Showing 7 changed files with 637 additions and 16 deletions.
2 changes: 2 additions & 0 deletions lang/en/enrol.php
Expand Up @@ -49,6 +49,7 @@
$string['enrolcandidatesmatching'] = 'Matching not enrolled users';
$string['enrolcohort'] = 'Enrol cohort';
$string['enrolcohortusers'] = 'Enrol users';
$string['enroldetails'] = 'Enrolment details';
$string['eventenrolinstancecreated'] = 'Enrolment instance created';
$string['eventenrolinstancedeleted'] = 'Enrolment instance deleted';
$string['eventenrolinstanceupdated'] = 'Enrolment instance updated';
Expand All @@ -59,6 +60,7 @@
$string['enrolmentinstances'] = 'Enrolment methods';
$string['enrolmentnew'] = 'New enrolment in {$a}';
$string['enrolmentnewuser'] = '{$a->user} has enrolled in course "{$a->course}"';
$string['enrolmentmethod'] = 'Enrolment method';
$string['enrolments'] = 'Enrolments';
$string['enrolmentoptions'] = 'Enrolment options';
$string['enrolnotpermitted'] = 'You do not have permission or are not allowed to enrol someone in this course';
Expand Down
1 change: 1 addition & 0 deletions user/amd/build/status_field.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

322 changes: 322 additions & 0 deletions user/amd/src/status_field.js
@@ -0,0 +1,322 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* AMD module for the user enrolment status field in the course participants page.
*
* @module core_user/status_field
* @copyright 2017 Jun Pataleta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['core/templates',
'jquery',
'core/str',
'core/config',
'core/notification',
'core/modal_factory',
'core/modal_events',
'core/fragment',
'core/ajax'
],
function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment, Ajax) {

/**
* Action selectors.
*
* @access private
* @type {{EDIT_ENROLMENT: string, SHOW_DETAILS: string, UNENROL: string}}
*/
var SELECTORS = {
EDIT_ENROLMENT: '[data-action="editenrolment"]',
SHOW_DETAILS: '[data-action="showdetails"]',
UNENROL: '[data-action="unenrol"]'
};

/**
* Constructor
*
* @param {Object} options Object containing options. The only valid option at this time is contextid.
* Each call to templates.render gets it's own instance of this class.
*/
var StatusFieldActions = function(options) {
this.contextid = options.contextid;
this.courseid = options.courseid;

// Bind click event to editenrol buttons.
this.bindEditEnrol();

// Bind click event to unenrol buttons.
this.bindUnenrol();

// Bind click event to status details buttons.
this.bindStatusDetails();
};
// Class variables and functions.

/** @var {number} courseid The course ID. */
StatusFieldActions.prototype.courseid = 0;

/**
* Private method
*
* @method initModal
* @private
*/
StatusFieldActions.prototype.bindEditEnrol = function() {
var statusFieldInstsance = this;

$(SELECTORS.EDIT_ENROLMENT).click(function(e) {
e.preventDefault();

// The particular edit button that was clicked.
var clickedEditTrigger = $(this);
// Get the parent container (it contains the data attributes associated with the status field).
var parentContainer = clickedEditTrigger.parent();
// Get the name of the user whose enrolment status is being edited.
var fullname = parentContainer.data('fullname');
// Get the user enrolment ID.
var ueid = clickedEditTrigger.attr('rel');

$.when(Str.get_string('edituserenrolment', 'enrol', fullname)).then(function(modalTitle) {
return ModalFactory.create({
large: true,
title: modalTitle,
type: ModalFactory.types.SAVE_CANCEL
});
}).done(function(modal) {
// Handle save event.
modal.getRoot().on(ModalEvents.save, function(e) {
// Don't close the modal yet.
e.preventDefault();
// Submit form data.
statusFieldInstsance.submitEditFormAjax(modal);
});

// Handle hidden event.
modal.getRoot().on(ModalEvents.hidden, function() {
// Destroy when hidden.
modal.destroy();
});

// Set the modal body.
modal.setBody(statusFieldInstsance.getBody(ueid));

// Show the modal!
modal.show();
}).fail(Notification.exception);
});
};

/**
* Private method
*
* @method bindUnenrol
* @private
*/
StatusFieldActions.prototype.bindUnenrol = function() {
$(SELECTORS.UNENROL).click(function(e) {
e.preventDefault();
var unenrolLink = $(this);
var parentContainer = unenrolLink.parent();
var strings = [
{
key: 'unenrol',
component: 'enrol'
},
{
key: 'unenrolconfirm',
component: 'enrol',
param: {
user: parentContainer.data('fullname'),
course: parentContainer.data('coursename')
}
}
];

$.when(Str.get_strings(strings)).then(function(results) {
var title = results[0];
var confirmMessage = results[1];
return ModalFactory.create({
body: confirmMessage,
large: true,
title: title,
type: ModalFactory.types.CONFIRM
});
}).done(function(modal) {
// Handle confirm event.
modal.getRoot().on(ModalEvents.yes, function() {
// Build params.
var unenrolParams = {
confirm: 1,
sesskey: Config.sesskey,
ue: $(unenrolLink).attr('rel')
};
// Send data to unenrol page (which will redirect back to the participants page after unenrol).
window.location.href = Config.wwwroot + '/enrol/unenroluser.php?' + $.param(unenrolParams);
});

// Handle hidden event.
modal.getRoot().on(ModalEvents.hidden, function() {
// Destroy when hidden.
modal.destroy();
});

// Display the delete confirmation modal.
modal.show();
}).fail(Notification.exception);
});
};

/**
* Private method
*
* @method bindStatusDetails
* @private
*/
StatusFieldActions.prototype.bindStatusDetails = function() {
$(SELECTORS.SHOW_DETAILS).click(function(e) {
e.preventDefault();

var detailsButton = $(this);
var parentContainer = detailsButton.parent();
var context = {
"fullname": parentContainer.data('fullname'),
"coursename": parentContainer.data('coursename'),
"enrolinstancename": parentContainer.data('enrolinstancename'),
"status": parentContainer.data('status'),
"timestart": parentContainer.data('timestart'),
"timeend": parentContainer.data('timeend')
};

var modalTitlePromise = Str.get_string('enroldetails', 'enrol');
var modalPromise = ModalFactory.create({large: true, type: ModalFactory.types.CANCEL});
$.when(modalTitlePromise, modalPromise).done(function(modalTitle, modal) {
var modalBodyPromise = Template.render('core_user/status_details', context);
modal.setTitle(modalTitle);
modal.setBody(modalBodyPromise);
modal.show();

// Handle hidden event.
modal.getRoot().on(ModalEvents.hidden, function() {
// Destroy when hidden.
modal.destroy();
});
}).fail(Notification.exception);
});
};

/**
* Private method
*
* @method submitEditFormAjax
* @param {Object} modal The the AMD modal object containing the form.
* @private
*/
StatusFieldActions.prototype.submitEditFormAjax = function(modal) {
var statusFieldInstsance = this;
var form = modal.getRoot().find('form');

// User enrolment ID.
var ueid = $(form).find('[name="ue"]').val();
// Status.
var status = $(form).find('[name="status"]').val();

var params = {
'courseid': this.courseid,
'ueid': ueid,
'status': status
};

// Enrol time start.
var timeStartEnabled = $(form).find('[name="timestart[enabled]"]');
if (timeStartEnabled.is(':checked')) {
var timeStartYear = $(form).find('[name="timestart[year]"]').val();
var timeStartMonth = $(form).find('[name="timestart[month]"]').val() - 1;
var timeStartDay = $(form).find('[name="timestart[day]"]').val();
var timeStartHour = $(form).find('[name="timestart[hour]"]').val();
var timeStartMinute = $(form).find('[name="timestart[minute]"]').val();
var timeStart = new Date(timeStartYear, timeStartMonth, timeStartDay, timeStartHour, timeStartMinute);
params.timestart = timeStart.getTime() / 1000;
}

// Enrol time end.
var timeEndEnabled = $(form).find('[name="timeend[enabled]"]');
if (timeEndEnabled.is(':checked')) {
var timeEndYear = $(form).find('[name="timeend[year]"]').val();
var timeEndMonth = $(form).find('[name="timeend[month]"]').val() - 1;
var timeEndDay = $(form).find('[name="timeend[day]"]').val();
var timeEndHour = $(form).find('[name="timeend[hour]"]').val();
var timeEndMinute = $(form).find('[name="timeend[minute]"]').val();
var timeEnd = new Date(timeEndYear, timeEndMonth, timeEndDay, timeEndHour, timeEndMinute);
params.timeend = timeEnd.getTime() / 1000;
}

var request = {
methodname: 'core_enrol_edit_user_enrolment',
args: params
};

Ajax.call([request])[0].done(function(data) {
if (data.result) {
// Dismiss the modal.
modal.hide();

// Reload the page, don't show changed data warnings.
if (typeof window.M.core_formchangechecker !== "undefined") {
window.M.core_formchangechecker.reset_form_dirty_state();
}
window.location.reload();

} else {
// Serialise the form data and reload the form fragment to show validation errors.
var formData = JSON.stringify(form.serialize());
modal.setBody(statusFieldInstsance.getBody(ueid, formData));
}
}).fail(Notification.exception);
};

/**
* Private method
*
* @method getBody
* @private
* @param {Number} ueid The user enrolment ID associated with the user.
* @param {string} formData Serialized string of the edit enrolment form data.
* @return {Promise}
*/
StatusFieldActions.prototype.getBody = function(ueid, formData) {
var params = {
'ueid': ueid
};
if (typeof formData !== 'undefined') {
params.formdata = formData;
}
return Fragment.loadFragment('enrol', 'user_enrolment_form', this.contextid, params).fail(Notification.exception);
};

return /** @alias module:core_user/editenrolment */ {
// Public variables and functions.
/**
* Every call to init creates a new instance of the class with it's own event listeners etc.
*
* @method init
* @public
* @param {object} config - config variables for the module.
*/
init: function(config) {
(new StatusFieldActions(config));
}
};
});

0 comments on commit 80d13bf

Please sign in to comment.