/* 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 }; }());