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
adc3c8f8
Commit
adc3c8f8
authored
Jan 06, 2017
by
Christina Roberts
Committed by
GitHub
Jan 06, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14134 from edx/christina/jsinput-newtemplate
New jsinput example problem
parents
7c7b4da7
96d99bf7
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
148 additions
and
120 deletions
+148
-120
common/lib/capa/capa/javascript_problem_generator.js
+0
-28
common/lib/capa/capa/javascript_problem_grader.js
+0
-26
common/lib/capa/capa/templates/chemicalequationinput.html
+1
-1
common/lib/capa/capa/templates/drag_and_drop_input.html
+1
-1
common/lib/capa/capa/templates/editageneinput.html
+1
-1
common/lib/capa/capa/templates/editamolecule.html
+1
-1
common/lib/capa/capa/templates/jsinput.html
+3
-3
common/lib/xmodule/xmodule/css/capa/display.scss
+0
-33
common/lib/xmodule/xmodule/templates/problem/jsinput_response.yaml
+30
-25
common/static/css/capa/jsinput_css.css
+0
-0
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
requirements/edx/github.txt
+1
-1
No files found.
common/lib/capa/capa/javascript_problem_generator.js
deleted
100644 → 0
View file @
7c7b4da7
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
()));
common/lib/capa/capa/javascript_problem_grader.js
deleted
100644 → 0
View file @
7c7b4da7
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
));
common/lib/capa/capa/templates/chemicalequationinput.html
View file @
adc3c8f8
...
...
@@ -11,7 +11,7 @@
%
endif
/>
<p
class=
"
status
"
>
<p
class=
"
indicator-container
"
>
${value|h}
<
%
include
file=
"status_span.html"
args=
"status=status, status_id=id"
/>
</p>
...
...
common/lib/capa/capa/templates/drag_and_drop_input.html
View file @
adc3c8f8
...
...
@@ -18,7 +18,7 @@
style=
"display:none;"
/>
<p
class=
"
status
drag-and-drop--status"
aria-describedby=
"input_${id}"
>
<p
class=
"
indicator-container
drag-and-drop--status"
aria-describedby=
"input_${id}"
>
<
%
include
file=
"status_span.html"
args=
"status=status, status_id=id"
/>
</p>
...
...
common/lib/capa/capa/templates/editageneinput.html
View file @
adc3c8f8
...
...
@@ -11,7 +11,7 @@
<input
type=
"hidden"
name=
"genex_problem_number"
id=
"genex_problem_number"
value =
"${genex_problem_number}"
></input>
<input
type=
"hidden"
name=
"input_${id}"
aria-describedby=
"answer_${id}"
id=
"input_${id}"
value=
"${value|h}"
/>
<p
class=
"
status
"
aria-describedby=
"input_${id}"
>
<p
class=
"
indicator-container
"
aria-describedby=
"input_${id}"
>
<
%
include
file=
"status_span.html"
args=
"status=status, status_id=id"
/>
</p>
...
...
common/lib/capa/capa/templates/editamolecule.html
View file @
adc3c8f8
...
...
@@ -16,7 +16,7 @@
<p
id=
"answer_${id}"
class=
"answer"
></p>
<p
class=
"
status
"
aria-describedby=
"input_${id}"
>
<p
class=
"
indicator-container
"
aria-describedby=
"input_${id}"
>
<
%
include
file=
"status_span.html"
args=
"status=status, status_id=id"
/>
</p>
...
...
common/lib/capa/capa/templates/jsinput.html
View file @
adc3c8f8
...
...
@@ -43,9 +43,9 @@
<br/>
<p
id=
"answer_${id}"
class=
"answer"
></p>
<
p
class=
"status
"
>
<
%
include
file=
"status_span.html"
args=
"status=status, status_id=id"
/>
</
p
>
<
div
class=
"indicator-container
"
>
<
%
include
file=
"status_span.html"
args=
"status=status, status_id=id"
/>
</
div
>
<div
class=
"error_message"
style=
"padding: 5px 5px 5px 5px; background-color:#FA6666; height:60px;width:400px; display: none"
></div>
...
...
common/lib/xmodule/xmodule/css/capa/display.scss
View file @
adc3c8f8
...
...
@@ -389,64 +389,31 @@ div.problem {
}
}
.unanswered
{
p
.status.drag-and-drop--status
{
@include
margin
(
8px
,
0
,
0
,
(
$baseline
/
2
));
text-indent
:
100%
;
white-space
:
nowrap
;
overflow
:
hidden
;
}
}
&
.correct
,
&
.ui-icon-check
{
p
.status
{
@include
status-icon
(
$correct
,
$checkmark-icon
);
}
input
{
border-color
:
$correct
;
}
}
&
.partially-correct
,
&
.ui-icon-check
{
p
.status
{
@include
status-icon
(
$partially-correct
,
$asterisk-icon
);
}
input
{
border-color
:
$partially-correct
;
}
}
&
.processing
{
p
.status
{
display
:
inline-block
;
width
:
20px
;
height
:
20px
;
background
:
url('
#{
$static-path
}
/images/spinner.gif')
center
center
no-repeat
;
}
input
{
border-color
:
#aaa
;
}
}
&
.ui-icon-close
{
p
.status
{
@include
status-icon
(
$incorrect
,
$cross-icon
);
}
input
{
border-color
:
$incorrect
;
}
}
&
.incorrect
,
&
.incomplete
{
p
.status
{
@include
status-icon
(
$incorrect
,
$cross-icon
);
}
input
{
border-color
:
$incorrect
;
}
...
...
common/lib/xmodule/xmodule/templates/problem/jsinput_response.yaml
View file @
adc3c8f8
---
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/css/capa/jsinput_css.css
deleted
100644 → 0
View file @
7c7b4da7
common/static/js/capa/jsinput/jsinput_example.css
0 → 100644
View file @
adc3c8f8
.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 @
adc3c8f8
<!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 @
adc3c8f8
/* 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
};
}());
requirements/edx/github.txt
View file @
adc3c8f8
...
...
@@ -53,7 +53,7 @@ git+https://github.com/edx/MongoDBProxy.git@25b99097615bda06bd7cdfe5669ed80dc2a7
git+https://github.com/edx/nltk.git@2.0.6#egg=nltk==2.0.6
-e git+https://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev
-e git+https://github.com/appliedsec/pygeoip.git@95e69341cebf5a6a9fbf7c4f5439d458898bdc3b#egg=pygeoip
-e git+https://github.com/jazkarta/edx-jsme.git@
0908b4db16168382be5685e7e9b7b4747ac410e0
#egg=edx-jsme
-e git+https://github.com/jazkarta/edx-jsme.git@
690dbf75441fa91c7c4899df0b83d77f7deb5458
#egg=edx-jsme
git+https://github.com/edx/django-pyfs.git@1.0.3#egg=django-pyfs==1.0.3
git+https://github.com/mitodl/django-cas.git@v2.1.1#egg=django-cas
-e git+https://github.com/dgrtwo/ParsePy.git@7949b9f754d1445eff8e8f20d0e967b9a6420639#egg=parse_rest
...
...
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