This takes into account the extra files that are usually required when copying problems containing JSInputs. Static files such as additional CSS and JS files needed to interact and style the problem.
88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
/* Original Source: https://files.edx.org/custom-js-example/jsinput_example.js */
|
|
|
|
/* globals Channel */
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// state will be populated via initial_state via the `setState` method. Defining dummy values here
|
|
// to make the expected structure clear.
|
|
var state = {
|
|
availableChoices: [],
|
|
selectedChoice: ''
|
|
},
|
|
channel,
|
|
select = document.getElementsByClassName('choices')[0],
|
|
feedback = document.getElementsByClassName('feedback')[0];
|
|
|
|
function populateSelect() {
|
|
// Populate the select from `state.availableChoices`.
|
|
var i, option;
|
|
|
|
// Clear out any pre-existing options.
|
|
while (select.firstChild) {
|
|
select.removeChild(select.firstChild);
|
|
}
|
|
|
|
// Populate the select with the available choices.
|
|
for (i = 0; i < state.availableChoices.length; i++) {
|
|
option = document.createElement('option');
|
|
option.value = i;
|
|
option.innerHTML = state.availableChoices[i];
|
|
if (state.availableChoices[i] === state.selectedChoice) {
|
|
option.selected = true;
|
|
}
|
|
select.appendChild(option);
|
|
}
|
|
feedback.innerText = "The currently selected answer is '" + state.selectedChoice + "'.";
|
|
}
|
|
|
|
function getGrade() {
|
|
// The following return value may or may not be used to grade server-side.
|
|
// If getState and setState are used, then the Python grader also gets access
|
|
// to the return value of getState and can choose it instead to grade.
|
|
return JSON.stringify(state.selectedChoice);
|
|
}
|
|
|
|
function getState() {
|
|
// Returns the current state (which can be used for grading).
|
|
return JSON.stringify(state);
|
|
}
|
|
|
|
// This function will be called with 1 argument when JSChannel is not used,
|
|
// 2 otherwise. In the latter case, the first argument is a transaction
|
|
// object that will not be used here
|
|
// (see http://mozilla.github.io/jschannel/docs/)
|
|
function setState() {
|
|
var stateString = arguments.length === 1 ? arguments[0] : arguments[1];
|
|
state = JSON.parse(stateString);
|
|
populateSelect();
|
|
}
|
|
|
|
// Establish a channel only if this application is embedded in an iframe.
|
|
// This will let the parent window communicate with this application using
|
|
// RPC and bypass SOP restrictions.
|
|
if (window.parent !== window) {
|
|
channel = Channel.build({
|
|
window: window.parent,
|
|
origin: '*',
|
|
scope: 'JSInput'
|
|
});
|
|
|
|
channel.bind('getGrade', getGrade);
|
|
channel.bind('getState', getState);
|
|
channel.bind('setState', setState);
|
|
}
|
|
|
|
select.addEventListener('change', function() {
|
|
state.selectedChoice = select.options[select.selectedIndex].text;
|
|
feedback.innerText = "You have selected '" + state.selectedChoice +
|
|
"'. Click Submit to grade your answer.";
|
|
});
|
|
|
|
return {
|
|
getState: getState,
|
|
setState: setState,
|
|
getGrade: getGrade
|
|
};
|
|
}()); |