Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
aa8d2226
Commit
aa8d2226
authored
Dec 06, 2016
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New example jsinput problem.
TNL-5893
parent
c3c86b8b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
140 additions
and
25 deletions
+140
-25
common/lib/xmodule/xmodule/templates/problem/jsinput_response.yaml
+30
-25
common/static/js/capa/jsinput/jsinput_example.css
+9
-0
common/static/js/capa/jsinput/jsinput_example.html
+15
-0
common/static/js/capa/jsinput/jsinput_example.js
+86
-0
No files found.
common/lib/xmodule/xmodule/templates/problem/jsinput_response.yaml
View file @
aa8d2226
---
metadata
:
display_name
:
Custom Java
s
cript Display and Grading
display_name
:
Custom Java
S
cript Display and Grading
markdown
:
!!null
showanswer
:
never
data
:
|
...
...
@@ -8,8 +8,8 @@ data: |
<p>
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
student
s can
interact with it in the LMS. You can grade your
student
s' work using
Studio embeds the problem in an IFrame so that your
learner
s can
interact with it in the LMS. You can grade your
learner
s' work using
JavaScript and some basic Python, and the grading is integrated into the
edX grading system.
</p>
...
...
@@ -31,42 +31,47 @@ data: |
<p>
When you add the problem, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply.
Also, be sure to specify a <strong>title</strong> attribute on the <strong>jsinput</strong> 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 <strong>html_file</strong> attribute.
</p>
<p>You can use the following example problem as a model.</p>
<customresponse cfn="
vglcf
n">
<customresponse cfn="
check_functio
n">
<script type="loncapa/python">
<![CDATA[
import json
def
vglcf
n(e, ans):
'''
par
is a dictionary that contains two keys, "answer" and "state".
def
check_functio
n(e, ans):
"""
"response"
is a dictionary that contains two keys, "answer" and "state".
The value of "answer" is the JSON string that "getGrade" returns.
The value of "state" is the JSON string that "getState" returns.
Clicking either "Submit" or "Save" registers the current state.
"""
response = json.loads(ans)
'''
par = json.loads(ans)
# You can use the value of the answer key to grade:
answer = json.loads(
par
["answer"])
return answer
["cylinder"] and not answer["cube"]
'''
answer = json.loads(
response
["answer"])
return answer
== "correct"
# Or you can use the value of the state key to grade:
state = json.loads(par["state"])
s
electedObjects = state["selectedObjects"]
return s
electedObjects["cylinder"] and not selectedObjects["cube"]
'''
"""
s
tate = json.loads(response["state"])
return s
tate["selectedChoice"] == "correct"
"""
]]>
</script>
<p>In the following image, click the objects until the cone is yellow and the cube is blue.</p>
<jsinput gradefn="WebGLDemo.getGrade"
get_statefn="WebGLDemo.getState"
set_statefn="WebGLDemo.setState"
initial_state='{"selectedObjects":{"cube":true,"cylinder":false}}'
width="400"
height="400"
html_file="https://studio.edx.org/c4x/edX/DemoX/asset/webGLDemo.html"
title="Spinning Cone and Cube"
<p>This is paragraph text displayed before the IFrame.</p>
<jsinput
gradefn="JSInputDemo.getGrade"
get_statefn="JSInputDemo.getState"
set_statefn="JSInputDemo.setState"
initial_state='{"selectedChoice": "incorrect1", "availableChoices": ["incorrect1", "correct", "incorrect2"]}'
width="600"
height="100"
html_file="https://files.edx.org/custom-js-example/jsinput_example.html"
title="Dropdown with Dynamic Text"
sop="false"/>
</customresponse>
</problem>
common/static/js/capa/jsinput/jsinput_example.css
0 → 100644
View file @
aa8d2226
.directions
{
font-size
:
large
}
.feedback
{
font-size
:
medium
;
border
:
2px
solid
cornflowerblue
;
padding
:
5px
;
}
common/static/js/capa/jsinput/jsinput_example.html
0 → 100644
View file @
aa8d2226
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<title>
Dropdown with Dynamic Text
</title>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"https://files.edx.org/custom-js-example/jsinput_example.css"
>
</head>
<body>
<script
src=
"https://files.edx.org/custom-js-example/jschannel.js"
></script>
<script
src=
"https://files.edx.org/custom-js-example/jsinput_example.js"
defer
></script>
<label
class=
"directions"
>
Select an option from the list:
<select
class=
"choices"
></select>
</label>
<p
aria-live=
"polite"
class=
"feedback"
></p>
</body>
</html>
common/static/js/capa/jsinput/jsinput_example.js
0 → 100644
View file @
aa8d2226
/* 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
};
}());
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment