Added ability to edit an element on the rearrange page

Increased the Moodle version required as this feature
uses the AMD module 'core/fragment' which was introduced
in 3.1.
This commit is contained in:
Mark Nelson 2016-06-13 19:39:57 +08:00
parent 65aee9c9c0
commit 555bca9ebb
13 changed files with 510 additions and 15 deletions

100
amd/src/dialogue.js Normal file
View file

@ -0,0 +1,100 @@
// 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/>.
/**
* Wrapper for the YUI M.core.notification class. Allows us to
* use the YUI version in AMD code until it is replaced.
*
* @module mod_customcert/dialogue
* @package mod_customcert
* @copyright 2016 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['core/yui'], function(Y) {
/**
* Constructor
*
* @param {String} title Title for the window.
* @param {String} content The content for the window.
* @param {function} afterShow Callback executed after the window is opened.
* @param {function} afterHide Callback executed after the window is closed.
* @param {Boolean} wide Specify we want an extra wide dialogue (the size is standard, but wider than the default).
*/
var dialogue = function(title, content, afterShow, afterHide, wide) {
this.yuiDialogue = null;
var parent = this;
// Default for wide is false.
if (typeof wide == 'undefined') {
wide = false;
}
Y.use('moodle-core-notification', 'timers', function () {
var width = '480px';
if (wide) {
width = '800px';
}
parent.yuiDialogue = new M.core.dialogue({
headerContent: title,
bodyContent: content,
draggable: true,
visible: false,
center: true,
modal: true,
width: width
});
parent.yuiDialogue.after('visibleChange', function(e) {
if (e.newVal) {
// Delay the callback call to the next tick, otherwise it can happen that it is
// executed before the dialogue constructor returns.
if ((typeof afterShow !== 'undefined')) {
Y.soon(function() {
afterShow(parent);
parent.yuiDialogue.centerDialogue();
});
}
} else {
if ((typeof afterHide !== 'undefined')) {
Y.soon(function() {
afterHide(parent);
});
}
}
});
parent.yuiDialogue.show();
});
};
/**
* Close this window.
*/
dialogue.prototype.close = function() {
this.yuiDialogue.hide();
this.yuiDialogue.destroy();
};
/**
* Get content.
*/
dialogue.prototype.getContent = function() {
return this.yuiDialogue.bodyNode.getDOMNode();
};
return /** @alias module:mod_customcert/dialogue */ dialogue;
});

148
amd/src/rearrange-area.js Normal file
View file

@ -0,0 +1,148 @@
// 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 used when rearranging a custom certificate.
*
* @module mod_customcert/rearrange-area
* @package mod_customcert
* @copyright 2016 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/yui', 'core/fragment', 'mod_customcert/dialogue', 'core/notification',
'core/str', 'core/templates', 'core/ajax'],
function($, Y, fragment, Dialogue, notification, str, template, ajax) {
/**
* RearrangeArea class.
*
* @param {String} selector The rearrange PDF selector
*/
var RearrangeArea = function(selector) {
this._node = $(selector);
this._setEvents();
};
RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPLEFT = 0;
RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPCENTER = 1;
RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPRIGHT = 2;
RearrangeArea.prototype._setEvents = function() {
this._node.on('click', '.element', this._editElement.bind(this));
};
RearrangeArea.prototype._editElement = function(event) {
var elementid = event.currentTarget.id.substr(8);
var contextid = this._node.attr('data-contextid');
var params = {
'elementid' : elementid
};
fragment.loadFragment('mod_customcert', 'editelement', contextid, params).done(function(html, js) {
str.get_string('editelement', 'mod_customcert').done(function(title) {
Y.use('moodle-core-formchangechecker', function () {
new Dialogue(
title,
'<div id=\'elementcontent\'></div>',
this._editElementDialogueConfig.bind(this, elementid, html, js),
undefined,
true
);
}.bind(this));
}.bind(this));
}.bind(this)).fail(notification.exception);
};
RearrangeArea.prototype._editElementDialogueConfig = function(elementid, html, js, popup) {
// Place the content in the dialogue.
template.replaceNode('#elementcontent', html, js);
// Add events for when we save, close and cancel the page.
var body = $(popup.getContent());
body.on('click', '#id_submitbutton', function(e) {
// Do not want to ask the user if they wish to stay on page after saving.
M.core_formchangechecker.reset_form_dirty_state();
// Save the data.
this._saveElement(elementid).always(function() {
// Update the DOM to reflect the adjusted value.
this._getElementHTML(elementid).always(function(html) {
var elementNode = this._node.find('#element-' + elementid);
var refpoint = $('#id_refpoint').val();
var refpointClass = '';
if (refpoint == this.CUSTOMCERT_REF_POINT_TOPLEFT) {
refpointClass = 'refpoint-left';
} else if (refpoint == this.CUSTOMCERT_REF_POINT_TOPCENTER) {
refpointClass = 'refpoint-center';
} else if (refpoint == this.CUSTOMCERT_REF_POINT_TOPRIGHT) {
refpointClass = 'refpoint-right';
}
elementNode.empty().append(html);
// Update the ref point.
elementNode.removeClass();
elementNode.addClass('element ' + refpointClass);
popup.close();
}.bind(this));
}.bind(this));
e.preventDefault();
}.bind(this));
body.on('click', '#id_cancel', function(e) {
popup.close();
e.preventDefault();
}.bind(this));
};
RearrangeArea.prototype._getElementHTML = function(elementid) {
// Get the variables we need.
var templateid = this._node.attr('data-templateid');
// Call the web service to get the updated element.
var promises = ajax.call([{
methodname: 'mod_customcert_get_element_html',
args: {
templateid : templateid,
elementid : elementid
}
}]);
// Return the promise.
return promises[0];
};
RearrangeArea.prototype._saveElement = function(elementid) {
// Get the variables we need.
var templateid = this._node.attr('data-templateid');
var inputs = $('#editelementform').serializeArray();
// Call the web service to save the element.
var promises = ajax.call([{
methodname: 'mod_customcert_save_element',
args: {
templateid : templateid,
elementid : elementid,
values : inputs
}
}]);
// Return the promise.
return promises[0];
};
return {
init : function(selector) {
new RearrangeArea(selector);
}
};
});