Skip to content

Commit

Permalink
MDL-67473 mod_lti: deeplinking multiple support
Browse files Browse the repository at this point in the history
AMOS BEGIN
 CPY [contentitem_help,mod_lti],[contentitem_deeplinking_help,mod_lti]
AMOS END
  • Loading branch information
claudevervoort committed Sep 30, 2020
1 parent 5486b03 commit 957da4b
Show file tree
Hide file tree
Showing 15 changed files with 553 additions and 123 deletions.
2 changes: 1 addition & 1 deletion mod/lti/amd/build/contentitem.min.js

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

2 changes: 1 addition & 1 deletion mod/lti/amd/build/contentitem.min.js.map

Large diffs are not rendered by default.

118 changes: 110 additions & 8 deletions mod/lti/amd/src/contentitem.js
Expand Up @@ -109,29 +109,131 @@ define(
new FormField('lineitemtag', FormField.TYPES.TEXT, true, '')
];

/**
* Hide the element, including aria and tab index.
* @param {HTMLElement} e the element to be hidden.
*/
const hideElement = (e) => {
e.setAttribute('hidden', 'true');
e.setAttribute('aria-hidden', 'true');
e.setAttribute('tab-index', '-1');
};

/**
* Show the element, including aria and tab index (set to 1).
* @param {HTMLElement} e the element to be shown.
*/
const showElement = (e) => {
e.removeAttribute('hidden');
e.setAttribute('aria-hidden', 'false');
e.setAttribute('tab-index', '1');
};

/**
* When more than one item needs to be added, the UI is simplified
* to just list the items to be added. Form is hidden and the only
* options is (save and return to course) or cancel.
* This function injects the summary to the form page, and hides
* the unneeded elements.
* @param {Object[]} items items to be added to the course.
*/
const showMultipleSummaryAndHideForm = async function(items) {
const form = document.querySelector('#region-main-box form');
const toolArea = form.querySelector('[data-attribute="dynamic-import"]');
const buttonGroup = form.querySelector('#fgroup_id_buttonar');
const submitAndLaunch = form.querySelector('#id_submitbutton');
Array.from(form.children).forEach(hideElement);
hideElement(submitAndLaunch);
const {html, js} = await templates.renderForPromise('mod_lti/tool_deeplinking_results',
{items: items});

await templates.replaceNodeContents(toolArea, html, js);
showElement(toolArea);
showElement(buttonGroup);
};

/**
* Transforms config values aimed at populating the lti mod form to JSON variant
* which are used to insert more than one activity modules in one submit
* by applying variation to the submitted form.
* See /course/modedit.php.
* @private
* @param {Object} config transforms a config to an actual form data to be posted.
* @return {Object} variant that will be used to modify form values on submit.
*/
var configToVariant = (config) => {
const variant = {};
['name', 'toolurl', 'securetoolurl', 'instructorcustomparameters', 'icon', 'secureicon', 'launchcontainer'].forEach(
function(name) {
variant[name] = config[name] || '';
}
);
variant['introeditor[text]'] = config.introeditor ? config.introeditor.text : '';
variant['introeditor[format]'] = config.introeditor ? config.introeditor.format : '';
if (config.instructorchoiceacceptgrades === 1) {
variant.instructorchoiceacceptgrades = '1';
variant['grade[modgrade_point]'] = config.grade_modgrade_point || '100';
} else {
variant.instructorchoiceacceptgrades = '0';
}
return variant;
};

/**
* Window function that can be called from mod_lti/contentitem_return to close the dialogue and process the return data.
* If the return data contains more than one item, the form will not be populated with item data
* but rather hidden, and the item data will be added to a single input field used to create multiple
* instances in one request.
*
* @param {object} returnData The fetched configuration data from the Content-Item selection dialogue.
*/
window.processContentItemReturnData = function(returnData) {
if (dialogue) {
dialogue.hide();
}

// Populate LTI configuration fields from return data.
var index;
for (index in ltiFormFields) {
var field = ltiFormFields[index];
var value = null;
if (typeof returnData[field.name] !== 'undefined') {
value = returnData[field.name];
if (returnData.multiple) {
for (index in ltiFormFields) {
// Name is required, so putting a placeholder as it will not be used
// in multi-items add.
ltiFormFields[index].setFieldValue(ltiFormFields[index].name === 'name' ? 'item' : null);
}
var variants = [];
returnData.multiple.forEach(function(v) {
variants.push(configToVariant(v));
});
showMultipleSummaryAndHideForm(returnData.multiple);
const submitAndCourse = document.querySelector('#id_submitbutton2');
submitAndCourse.onclick = (e) => {
e.preventDefault();
submitAndCourse.disabled = true;
const fd = new FormData(document.querySelector('form.mform'));
const postVariant = (promise, variant) => {
Object.entries(variant).forEach((entry) => fd.set(entry[0], entry[1]));
const body = new URLSearchParams(fd);
const doPost = () => fetch(document.location.pathname, {method: 'post', body});
return promise.then(doPost).catch(doPost);
};
const backToCourse = () => {
document.querySelector("#id_cancel").click();
};
variants.reduce(postVariant, Promise.resolve()).then(backToCourse).catch(backToCourse);
};
} else {
// Populate LTI configuration fields from return data.
for (index in ltiFormFields) {
var field = ltiFormFields[index];
var value = null;
if (typeof returnData[field.name] !== 'undefined') {
value = returnData[field.name];
}
field.setFieldValue(value);
}
field.setFieldValue(value);
}

if (doneCallback) {
doneCallback();
doneCallback(returnData);
}
};

Expand Down
2 changes: 1 addition & 1 deletion mod/lti/auth.php
Expand Up @@ -120,7 +120,7 @@
$title = base64_decode($titleb64);
$text = base64_decode($textb64);
$request = lti_build_content_item_selection_request($typeid, $course, $returnurl, $title, $text,
[], [], false, false, false, false, false, $nonce);
[], [], false, true, false, false, false, $nonce);
$endpoint = $request->url;
$params = $request->params;
}
Expand Down
13 changes: 8 additions & 5 deletions mod/lti/edit_form.php
Expand Up @@ -214,17 +214,15 @@ public function definition() {
$mform->addHelpButton('lti_launchcontainer', 'default_launch_container', 'lti');
$mform->setType('lti_launchcontainer', PARAM_INT);

$mform->addElement('advcheckbox', 'lti_contentitem', get_string('contentitem', 'lti'));
$mform->addHelpButton('lti_contentitem', 'contentitem', 'lti');
$mform->setAdvanced('lti_contentitem');
$mform->addElement('advcheckbox', 'lti_contentitem', get_string('contentitem_deeplinking', 'lti'));
$mform->addHelpButton('lti_contentitem', 'contentitem_deeplinking', 'lti');
if ($istool) {
$mform->disabledIf('lti_contentitem', null);
}

$mform->addElement('text', 'lti_toolurl_ContentItemSelectionRequest',
get_string('toolurl_contentitemselectionrequest', 'lti'), array('size' => '64'));
$mform->setType('lti_toolurl_ContentItemSelectionRequest', PARAM_URL);
$mform->setAdvanced('lti_toolurl_ContentItemSelectionRequest');
$mform->addHelpButton('lti_toolurl_ContentItemSelectionRequest', 'toolurl_contentitemselectionrequest', 'lti');
$mform->disabledIf('lti_toolurl_ContentItemSelectionRequest', 'lti_contentitem', 'notchecked');
if ($istool) {
Expand Down Expand Up @@ -271,7 +269,12 @@ public function definition() {
// LTI Extensions.

// Add grading preferences fieldset where the tool is allowed to return grades.
$mform->addElement('select', 'lti_acceptgrades', get_string('accept_grades_admin', 'lti'), $options);
$gradeoptions = array();
$gradeoptions[] = get_string('never', 'lti');
$gradeoptions[] = get_string('always', 'lti');
$gradeoptions[] = get_string('delegate_tool', 'lti');

$mform->addElement('select', 'lti_acceptgrades', get_string('accept_grades_admin', 'lti'), $gradeoptions);
$mform->setType('lti_acceptgrades', PARAM_INT);
$mform->setDefault('lti_acceptgrades', '2');
$mform->addHelpButton('lti_acceptgrades', 'accept_grades_admin', 'lti');
Expand Down
2 changes: 2 additions & 0 deletions mod/lti/lang/en/deprecated.txt
@@ -1,3 +1,5 @@
leaveblank,mod_lti
organizationid,mod_lti
organizationid_help,mod_lti
contentitem,mod_lti
contentitem_help,mod_lti
12 changes: 10 additions & 2 deletions mod/lti/lang/en/lti.php
Expand Up @@ -108,8 +108,10 @@
$string['configtypes'] = 'Enable LTI applications';
$string['configured'] = 'Configured';
$string['confirmtoolactivation'] = 'Are you sure you would like to activate this tool?';
$string['contentitem'] = 'Content-Item Message';
$string['contentitem_help'] = 'If ticked, the option \'Select content\' will be available when adding an external tool.';
$string['contentitem_deeplinking'] = 'Supports Deep Linking (Content-Item Message)';
$string['contentitem_deeplinking_help'] = 'If ticked, the option \'Select content\' will be available when adding an external tool.';
$string['contentitem_multiple_description'] = 'The following items will be added to your course:';
$string['contentitem_multiple_graded'] = 'Graded activity (Maximum grade: {$a})';
$string['course_tool_types'] = 'Course tools';
$string['courseactivitiesorresources'] = 'Course activities or resources';
$string['courseid'] = 'Course ID number';
Expand Down Expand Up @@ -141,6 +143,7 @@
Depending on the browser, it will open in a new tab or a popup window.
It is possible that browsers will prevent the new window from opening.';
$string['delegate'] = 'Delegate to teacher';
$string['delegate_tool'] = 'As specified in Deep Linking definition or Delegate to teacher';
$string['delete'] = 'Delete';
$string['delete_confirmation'] = 'Are you sure you want to delete this preconfigured tool?';
$string['deletetype'] = 'Delete preconfigured tool';
Expand Down Expand Up @@ -593,3 +596,8 @@
$string['organizationid_help'] = 'A unique identifier for this Moodle instance. Typically, the DNS name of the organisation is used.
If this field is left blank, the host name of this Moodle site will be used as the default value.';

// Deprecated since Moodle 3.10.
$string['contentitem'] = 'Content-Item Message';
$string['contentitem_help'] = 'If ticked, the option \'Select content\' will be available when adding an external tool.';

0 comments on commit 957da4b

Please sign in to comment.