You can include custom JavaScript applications (also called custom JavaScript problems or JS input problems) in a course. You add the application directly into edX Studio.
When you create a JavaScript application, Studio embeds the problem in an inline
frame (HTML iframe
tag) so that learners can interact with it in the LMS.
See the following sections for more information:
See The Custom JavaScript Display and Grading Example Template for information about the template application built in to edX Studio.
Course teams should see the following sections of the Building and Running an edX Course guide.
The rest of this section provides more information for developers who are creating JavaScript applications for courses on the edX platform.
Note
This section assumes proficiency with JavaScript and with how problems are constructed in edX Studio. If you intend to grade learners’ interactions with your JavaScript application, you must also be proficient with Python.
When using a JavaScript application in your course content, you have three options.
These options are explained through examples below.
The simplest option is to use JavaScript to show content to learners, and optionally to provide feedback as a formative assessment.
<customresponse>
<jsinput
width="width needed to display your application"
height="height needed to display your application"
html_file="Embed URL of the HTML file"
sop="false"/>
</customresponse>
For example:
<customresponse>
<jsinput
width="400"
height="400"
html_file="/static/electrol_demo.html"
sop="false"/>
</customresponse>
To use a JavaScript Application for a summative assessment and have learner results calculated by the edX grading system, you must:
Your application must contain a getState()
function that returns the state
of all objects as a JSON string.
The getState()
function retrieves the state of objects in the application,
so each learner experiences that application in its initial or last saved state.
The name of the getState()
function must be the value of the get_statefn
attribute of the jsinput
element for the problem.
For example:
<customresponse cfn="vglcfn">
<jsinput get_statefn="JSObject.getState"
. . . .
Your application must contain a setState()
function.
The setState()
function is executed when the learner selects Submit.
The function saves application’s state so that the learner can later return to the application and find it as he or she left it.
The name of the setState()
function must be the value of the set_statefn
attribute of the jsinput
element for the problem.
For example:
<customresponse cfn="vglcfn">
<jsinput set_statefn="JSObject.setState"
. . . .
Your application must contain a getGrade()
function.
The getGrade()
function is executed when the learner selects Submit.
The getState()
function must return the state of objects on which grading
is based as a JSON string.
The JSON string returned by getGrade()
is used by the Python code in the
problem to determine the learner’s results, as explained below.
The name of the getGrade()
function must be the value of the gradefn
attribute of the jsinput
element for the problem.
For example:
<customresponse cfn="vglcfn">
<jsinput gradefn="JSObject.getGrade"
. . . .
To grade a learner’s interaction with your JavaScript application, you must
write Python code in the problem. When a learner selects Submit, the
Python code parses the JSON string returned by the application’s
getGrade()
function and determines if the learner’s submission is correct
or not.
Note
Grading for JavaScript applications supports determining if a learner’s submission is correct or not. You cannot give partial credit with JavaScript applications.
In the Python code, make sure you follow these guidelines.
script
element of type loncapa/python
.json
customresponse
element that defines the problem.vglcfn
e
for the submission event, and ans
, which is
the JSON string returned by the JavaScript function getGrade()
.True
if the learner’s submission is correct, or False
if
it is incorrect.The structure of the Python code in the problem is shown in this example.
<problem>
<script type="loncapa/python">
import json
def vglcfn(e, ans):
"""
Code that parses ans and returns True or False
"""
</script>
<customresponse cfn="vglcfn">
. . . .
</problem>
The problem component XML that you define in Studio to provide learners with a JavaScript application has the following structure.
<problem>
<!-- Optional script tag for summative assessments -->
<script type="loncapa/python">
import json
def vglcfn(e, ans):
"""
Code that parses ans and returns True or False
"""
</script>
<customresponse cfn="vglcfn">
<jsinput
gradefn="JSObject.getGrade"
get_statefn="JSObject.getState"
set_statefn="JSObject.setState"
width="100%"
height="360"
html_file="/static/file-name.html"
sop="false"/>
</customresponse>
</problem>
The following table describes the attributes of the jsinput
element.
Attribute | Description | Example |
---|---|---|
gradefn | The function in your JavaScript application that returns the state of the objects to be evaluated as a JSON string. | JSObject.getGrade |
get_statefun | The function in your JavaScript application that returns the state of the objects. | JSObject.getState |
set_statefun | The function in your JavaScript application that saves the state of the objects. | JSObject.setState |
initial_state | A JSON string representing the initial state, if any, of the objects. | ‘{“selectedObjects”:{“cube”:true,”cylinder”:false}}’ |
width | The width of the iframe in which your JavaScript application will be displayed, in pixels. | 400 |
height | The height of the iframe in which your JavaScript application will be displayed, in pixels. | 400 |
html_file | The name of the HTML file containing your JavaScript application that will be loaded in the iframe. | /static/webGLDemo.html |
sop | The same-origin policy (SOP), meaning that all elements have the same
protocol, host, and port. To bypass the SOP, set to true . |
false |