In these problems (also called custom JavaScript problems or JS Input
problems), you add a problem or tool that uses JavaScript in Studio.
- Studio embeds the problem in an IFrame so that your students can
- interact with it in the LMS. You can grade your students' work using
+ Studio embeds the problem in an IFrame so that your learners can
+ interact with it in the LMS. You can grade your learners' work using
JavaScript and some basic Python, and the grading is integrated into the
edX grading system.
@@ -31,42 +31,47 @@ data: |
When you add the problem, be sure to select Settings
to specify a Display Name and other values that apply.
+ Also, be sure to specify a title attribute on the jsinput tag;
+ this title is used for the title attribute on the generated IFrame. Generally,
+ the title attribute on the IFrame should match the title tag of the HTML hosted
+ within the IFrame, which is specified by the html_file attribute.
You can use the following example problem as a model.
-
+
-
In the following image, click the objects until the cone is yellow and the cube is blue.
- This is paragraph text displayed before the IFrame.
+
diff --git a/common/static/js/capa/jsinput/jsinput_example.css b/common/static/js/capa/jsinput/jsinput_example.css
new file mode 100644
index 0000000000..8f1144ac40
--- /dev/null
+++ b/common/static/js/capa/jsinput/jsinput_example.css
@@ -0,0 +1,9 @@
+.directions {
+ font-size: large
+}
+
+.feedback {
+ font-size: medium;
+ border: 2px solid cornflowerblue;
+ padding: 5px;
+}
diff --git a/common/static/js/capa/jsinput/jsinput_example.html b/common/static/js/capa/jsinput/jsinput_example.html
new file mode 100644
index 0000000000..caa034fff9
--- /dev/null
+++ b/common/static/js/capa/jsinput/jsinput_example.html
@@ -0,0 +1,15 @@
+
+
+
+ Dropdown with Dynamic Text
+
+
+
+
+
+
+
+
+
diff --git a/common/static/js/capa/jsinput/jsinput_example.js b/common/static/js/capa/jsinput/jsinput_example.js
new file mode 100644
index 0000000000..6aa125fd69
--- /dev/null
+++ b/common/static/js/capa/jsinput/jsinput_example.js
@@ -0,0 +1,86 @@
+/* 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
+ };
+}());
From 77be91baf9558d09baf167ddeda0c2a961934a3e Mon Sep 17 00:00:00 2001
From: cahrens
Date: Mon, 12 Dec 2016 11:05:18 -0500
Subject: [PATCH 2/4] Related to javascriptresponse, which was already deleted.
I missed these files the first time around.
---
.../capa/capa/javascript_problem_generator.js | 28 -------------------
.../capa/capa/javascript_problem_grader.js | 26 -----------------
2 files changed, 54 deletions(-)
delete mode 100644 common/lib/capa/capa/javascript_problem_generator.js
delete mode 100644 common/lib/capa/capa/javascript_problem_grader.js
diff --git a/common/lib/capa/capa/javascript_problem_generator.js b/common/lib/capa/capa/javascript_problem_generator.js
deleted file mode 100644
index 473a5d8e8c..0000000000
--- a/common/lib/capa/capa/javascript_problem_generator.js
+++ /dev/null
@@ -1,28 +0,0 @@
-require('coffee-script');
-var importAll = function(modulePath) {
- module = require(modulePath);
- for (key in module) {
- global[key] = module[key];
- }
-};
-
-importAll('mersenne-twister-min');
-importAll('xproblem');
-
-generatorModulePath = process.argv[2];
-dependencies = JSON.parse(process.argv[3]);
-seed = JSON.parse(process.argv[4]);
-params = JSON.parse(process.argv[5]);
-
-if (seed == null) {
- seed = 4;
-}
-
-for (var i = 0; i < dependencies.length; i++) {
- importAll(dependencies[i]);
-}
-
-generatorModule = require(generatorModulePath);
-generatorClass = generatorModule.generatorClass;
-generator = new generatorClass(seed, params);
-console.log(JSON.stringify(generator.generate()));
diff --git a/common/lib/capa/capa/javascript_problem_grader.js b/common/lib/capa/capa/javascript_problem_grader.js
deleted file mode 100644
index 02cb7da7f2..0000000000
--- a/common/lib/capa/capa/javascript_problem_grader.js
+++ /dev/null
@@ -1,26 +0,0 @@
-require('coffee-script');
-var importAll = function(modulePath) {
- module = require(modulePath);
- for (key in module) {
- global[key] = module[key];
- }
-};
-
-importAll('xproblem');
-
-graderModulePath = process.argv[2];
-dependencies = JSON.parse(process.argv[3]);
-submission = JSON.parse(process.argv[4]);
-problemState = JSON.parse(process.argv[5]);
-params = JSON.parse(process.argv[6]);
-
-for (var i = 0; i < dependencies.length; i++) {
- importAll(dependencies[i]);
-}
-
-graderModule = require(graderModulePath);
-graderClass = graderModule.graderClass;
-grader = new graderClass(submission, problemState, params);
-console.log(JSON.stringify(grader.grade()));
-console.log(JSON.stringify(grader.evaluation));
-console.log(JSON.stringify(grader.solution));
From ed614448e487f99d689609d6e11e404952c038be Mon Sep 17 00:00:00 2001
From: cahrens
Date: Tue, 20 Dec 2016 12:33:28 -0500
Subject: [PATCH 3/4] Cleanup of status.
Also remove unused empty jsinput_css.css.
---
.../capa/templates/chemicalequationinput.html | 2 +-
.../capa/templates/drag_and_drop_input.html | 2 +-
.../capa/capa/templates/editageneinput.html | 2 +-
.../capa/capa/templates/editamolecule.html | 2 +-
common/lib/capa/capa/templates/jsinput.html | 6 ++--
.../lib/xmodule/xmodule/css/capa/display.scss | 33 -------------------
common/static/css/capa/jsinput_css.css | 0
7 files changed, 7 insertions(+), 40 deletions(-)
delete mode 100644 common/static/css/capa/jsinput_css.css
diff --git a/common/lib/capa/capa/templates/chemicalequationinput.html b/common/lib/capa/capa/templates/chemicalequationinput.html
index b61172951a..3f18a699e6 100644
--- a/common/lib/capa/capa/templates/chemicalequationinput.html
+++ b/common/lib/capa/capa/templates/chemicalequationinput.html
@@ -11,7 +11,7 @@
% endif
/>
-