Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
problem-builder
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
OpenEdx
problem-builder
Commits
6a45664a
Commit
6a45664a
authored
Sep 18, 2015
by
Tim Krones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Address review comments.
parent
b285ea7e
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
62 additions
and
59 deletions
+62
-59
problem_builder/mentoring.py
+12
-11
problem_builder/public/js/mentoring_with_steps.js
+34
-41
problem_builder/step.py
+10
-5
problem_builder/templates/html/mentoring_with_steps.html
+6
-2
No files found.
problem_builder/mentoring.py
View file @
6a45664a
...
@@ -835,7 +835,7 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -835,7 +835,7 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
)
)
# User state
# User state
step
=
Integer
(
active_
step
=
Integer
(
# Keep track of the student progress.
# Keep track of the student progress.
default
=
0
,
default
=
0
,
scope
=
Scope
.
user_state
,
scope
=
Scope
.
user_state
,
...
@@ -862,22 +862,23 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -862,22 +862,23 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
def
student_view
(
self
,
context
):
def
student_view
(
self
,
context
):
fragment
=
Fragment
()
fragment
=
Fragment
()
child
_content
=
u""
child
ren_contents
=
[]
for
child_id
in
self
.
children
:
for
child_id
in
self
.
children
:
child
=
self
.
runtime
.
get_block
(
child_id
)
child
=
self
.
runtime
.
get_block
(
child_id
)
if
child
is
None
:
# child should not be None but it can happen due to bugs or permission issues
if
child
is
None
:
# child should not be None but it can happen due to bugs or permission issues
child_content
+
=
u"<p>[{}]</p>"
.
format
(
self
.
_
(
u"Error: Unable to load child component."
))
child_content
=
u"<p>[{}]</p>"
.
format
(
self
.
_
(
u"Error: Unable to load child component."
))
elif
not
isinstance
(
child
,
MentoringMessageBlock
):
elif
not
isinstance
(
child
,
MentoringMessageBlock
):
child_fragment
=
self
.
_render_child_fragment
(
child
,
context
,
view
=
'mentoring_view'
)
child_fragment
=
self
.
_render_child_fragment
(
child
,
context
,
view
=
'mentoring_view'
)
fragment
.
add_frag_resources
(
child_fragment
)
fragment
.
add_frag_resources
(
child_fragment
)
child_content
+=
child_fragment
.
content
child_content
=
child_fragment
.
content
children_contents
.
append
(
child_content
)
fragment
.
add_content
(
loader
.
render_template
(
'templates/html/mentoring_with_steps.html'
,
{
fragment
.
add_content
(
loader
.
render_template
(
'templates/html/mentoring_with_steps.html'
,
{
'self'
:
self
,
'self'
:
self
,
'title'
:
self
.
display_name
,
'title'
:
self
.
display_name
,
'show_title'
:
self
.
show_title
,
'show_title'
:
self
.
show_title
,
'child
_content'
:
child_content
,
'child
ren_contents'
:
children_contents
,
}))
}))
fragment
.
add_css_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/css/problem-builder.css'
))
fragment
.
add_css_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/css/problem-builder.css'
))
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/js/mentoring_with_steps.js'
))
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/js/mentoring_with_steps.js'
))
...
@@ -909,16 +910,16 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -909,16 +910,16 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
]
]
@XBlock.json_handler
@XBlock.json_handler
def
update_
step
(
self
,
step
,
suffix
=
''
):
def
update_
active_step
(
self
,
new_value
,
suffix
=
''
):
if
step
<
len
(
self
.
steps
):
if
new_value
<
len
(
self
.
steps
):
self
.
step
=
step
self
.
active_step
=
new_value
return
{
return
{
'
step'
:
self
.
step
'
active_step'
:
self
.
active_
step
}
}
@XBlock.json_handler
@XBlock.json_handler
def
try_again
(
self
,
data
,
suffix
=
''
):
def
try_again
(
self
,
data
,
suffix
=
''
):
self
.
step
=
0
self
.
active_
step
=
0
step_blocks
=
[
self
.
runtime
.
get_block
(
child_id
)
for
child_id
in
self
.
steps
]
step_blocks
=
[
self
.
runtime
.
get_block
(
child_id
)
for
child_id
in
self
.
steps
]
...
@@ -926,7 +927,7 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -926,7 +927,7 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
step
.
reset
()
step
.
reset
()
return
{
return
{
'
result'
:
'success'
'
active_step'
:
self
.
active_step
}
}
def
author_edit_view
(
self
,
context
):
def
author_edit_view
(
self
,
context
):
...
...
problem_builder/public/js/mentoring_with_steps.js
View file @
6a45664a
...
@@ -3,24 +3,24 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -3,24 +3,24 @@ function MentoringWithStepsBlock(runtime, element) {
var
steps
=
runtime
.
children
(
element
).
filter
(
var
steps
=
runtime
.
children
(
element
).
filter
(
function
(
c
)
{
return
c
.
element
.
className
.
indexOf
(
'pb-mentoring-step'
)
>
-
1
;
}
function
(
c
)
{
return
c
.
element
.
className
.
indexOf
(
'pb-mentoring-step'
)
>
-
1
;
}
);
);
var
step
=
$
(
'.mentoring'
,
element
).
data
(
'
step'
);
var
activeStep
=
$
(
'.mentoring'
,
element
).
data
(
'active-
step'
);
var
active_child
,
checkmark
,
submitDOM
,
nextDOM
,
tryAgainDOM
,
submitXHR
;
var
checkmark
,
submitDOM
,
nextDOM
,
tryAgainDOM
,
submitXHR
;
function
isLast
Child
()
{
function
isLast
Step
()
{
return
(
active
_child
===
steps
.
length
-
1
);
return
(
active
Step
===
steps
.
length
-
1
);
}
}
function
update
Step
(
)
{
function
update
ActiveStep
(
newValue
)
{
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'update_step'
);
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'update_
active_
step'
);
$
.
post
(
handlerUrl
,
JSON
.
stringify
(
step
+
1
))
$
.
post
(
handlerUrl
,
JSON
.
stringify
(
newValue
))
.
success
(
function
(
response
)
{
.
success
(
function
(
response
)
{
step
=
response
.
step
;
activeStep
=
response
.
active_
step
;
});
});
}
}
function
handleResults
(
response
)
{
function
handleResults
(
response
)
{
// Update step so next step is shown on page reload (even if user does not click "Next Step")
// Update
active
step so next step is shown on page reload (even if user does not click "Next Step")
update
Step
(
);
update
ActiveStep
(
activeStep
+
1
);
// Update UI
// Update UI
if
(
response
.
completed
===
'correct'
)
{
if
(
response
.
completed
===
'correct'
)
{
...
@@ -36,16 +36,16 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -36,16 +36,16 @@ function MentoringWithStepsBlock(runtime, element) {
nextDOM
.
removeAttr
(
"disabled"
);
nextDOM
.
removeAttr
(
"disabled"
);
if
(
nextDOM
.
is
(
':visible'
))
{
nextDOM
.
focus
();
}
if
(
nextDOM
.
is
(
':visible'
))
{
nextDOM
.
focus
();
}
if
(
isLast
Child
())
{
if
(
isLast
Step
())
{
tryAgainDOM
.
removeAttr
(
'disabled'
);
tryAgainDOM
.
removeAttr
(
'disabled'
);
tryAgainDOM
.
show
();
tryAgainDOM
.
show
();
}
}
}
}
function
submit
()
{
function
submit
()
{
// We do not handle submissions at this level, so just forward to "submit" method of
current
step
// We do not handle submissions at this level, so just forward to "submit" method of
active
step
var
child
=
steps
[
active_child
];
var
step
=
steps
[
activeStep
];
child
[
'submit'
]
(
handleResults
);
step
.
submit
(
handleResults
);
}
}
function
hideAllSteps
()
{
function
hideAllSteps
()
{
...
@@ -61,23 +61,21 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -61,23 +61,21 @@ function MentoringWithStepsBlock(runtime, element) {
hideAllSteps
();
hideAllSteps
();
}
}
function
displayNextChild
()
{
function
updateDisplay
()
{
cleanAll
();
cleanAll
();
findNextChild
();
showActiveStep
();
nextDOM
.
attr
(
'disabled'
,
'disabled'
);
nextDOM
.
attr
(
'disabled'
,
'disabled'
);
validateXBlock
();
validateXBlock
();
}
}
function
findNextChild
()
{
function
showActiveStep
()
{
// find the next real child block to display. HTMLBlock are always displayed
var
step
=
steps
[
activeStep
];
++
active_child
;
$
(
step
.
element
).
show
();
var
child
=
steps
[
active_child
];
$
(
child
.
element
).
show
();
}
}
function
onChange
()
{
function
onChange
()
{
// We do not allow users to modify answers belonging to a step after submitting them:
// We do not allow users to modify answers belonging to a step after submitting them:
// Once an answer has been submitted (
next
button is enabled),
// Once an answer has been submitted (
"Next Step"
button is enabled),
// start ignoring changes to the answer.
// start ignoring changes to the answer.
if
(
nextDOM
.
attr
(
'disabled'
))
{
if
(
nextDOM
.
attr
(
'disabled'
))
{
validateXBlock
();
validateXBlock
();
...
@@ -85,17 +83,17 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -85,17 +83,17 @@ function MentoringWithStepsBlock(runtime, element) {
}
}
function
validateXBlock
()
{
function
validateXBlock
()
{
var
is
_v
alid
=
true
;
var
is
V
alid
=
true
;
var
child
=
steps
[
active_child
];
var
step
=
steps
[
activeStep
];
if
(
child
)
{
if
(
step
)
{
is
_valid
=
child
[
'validate'
]
();
is
Valid
=
step
.
validate
();
}
}
if
(
!
is
_v
alid
)
{
if
(
!
is
V
alid
)
{
submitDOM
.
attr
(
'disabled'
,
'disabled'
);
submitDOM
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
}
else
{
submitDOM
.
removeAttr
(
'disabled'
);
submitDOM
.
removeAttr
(
'disabled'
);
}
}
if
(
isLast
Child
())
{
if
(
isLast
Step
())
{
nextDOM
.
hide
();
nextDOM
.
hide
();
}
}
}
}
...
@@ -103,19 +101,16 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -103,19 +101,16 @@ function MentoringWithStepsBlock(runtime, element) {
function
initSteps
(
options
)
{
function
initSteps
(
options
)
{
for
(
var
i
=
0
;
i
<
steps
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
steps
.
length
;
i
++
)
{
var
step
=
steps
[
i
];
var
step
=
steps
[
i
];
step
[
'initChildren'
]
(
options
);
step
.
initChildren
(
options
);
}
}
}
}
function
handleTryAgain
(
result
)
{
function
handleTryAgain
(
result
)
{
if
(
result
.
result
!==
'success'
)
activeStep
=
result
.
active_step
;
return
;
updateDisplay
();
active_child
=
-
1
;
displayNextChild
();
tryAgainDOM
.
hide
();
tryAgainDOM
.
hide
();
submitDOM
.
show
();
submitDOM
.
show
();
if
(
!
isLast
Child
())
{
if
(
!
isLast
Step
())
{
nextDOM
.
show
();
nextDOM
.
show
();
}
}
}
}
...
@@ -132,24 +127,22 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -132,24 +127,22 @@ function MentoringWithStepsBlock(runtime, element) {
checkmark
=
$
(
'.assessment-checkmark'
,
element
);
checkmark
=
$
(
'.assessment-checkmark'
,
element
);
submitDOM
=
$
(
element
).
find
(
'.submit .input-main'
);
submitDOM
=
$
(
element
).
find
(
'.submit .input-main'
);
submitDOM
.
bind
(
'click'
,
submit
);
submitDOM
.
on
(
'click'
,
submit
);
submitDOM
.
show
();
submitDOM
.
show
();
nextDOM
=
$
(
element
).
find
(
'.submit .input-next'
);
nextDOM
=
$
(
element
).
find
(
'.submit .input-next'
);
nextDOM
.
bind
(
'click'
,
displayNextChild
);
nextDOM
.
on
(
'click'
,
updateDisplay
);
nextDOM
.
show
();
nextDOM
.
show
();
tryAgainDOM
=
$
(
element
).
find
(
'.submit .input-try-again'
);
tryAgainDOM
=
$
(
element
).
find
(
'.submit .input-try-again'
);
tryAgainDOM
.
bind
(
'click'
,
tryAgain
);
tryAgainDOM
.
on
(
'click'
,
tryAgain
);
var
options
=
{
var
options
=
{
onChange
:
onChange
onChange
:
onChange
};
};
initSteps
(
options
);
initSteps
(
options
);
active_child
=
step
;
updateDisplay
();
active_child
-=
1
;
displayNextChild
();
}
}
initXBlockView
();
initXBlockView
();
...
...
problem_builder/step.py
View file @
6a45664a
...
@@ -58,6 +58,12 @@ def _normalize_id(key):
...
@@ -58,6 +58,12 @@ def _normalize_id(key):
return
key
return
key
class
Correctness
(
object
):
CORRECT
=
'correct'
PARTIAL
=
'partial'
INCORRECT
=
'incorrect'
class
HtmlBlockShim
(
object
):
class
HtmlBlockShim
(
object
):
CATEGORY
=
'html'
CATEGORY
=
'html'
STUDIO_LABEL
=
_
(
u"HTML"
)
STUDIO_LABEL
=
_
(
u"HTML"
)
...
@@ -127,18 +133,17 @@ class MentoringStepBlock(
...
@@ -127,18 +133,17 @@ class MentoringStepBlock(
child
.
save
()
child
.
save
()
# Update results stored for this step
# Update results stored for this step
while
self
.
student_results
:
self
.
reset
()
self
.
student_results
.
pop
()
for
result
in
submit_results
:
for
result
in
submit_results
:
self
.
student_results
.
append
(
result
)
self
.
student_results
.
append
(
result
)
# Compute "answer status" for this step
# Compute "answer status" for this step
if
all
(
result
[
1
][
'status'
]
==
'correct'
for
result
in
submit_results
):
if
all
(
result
[
1
][
'status'
]
==
'correct'
for
result
in
submit_results
):
completed
=
'correct'
completed
=
Correctness
.
CORRECT
elif
all
(
result
[
1
][
'status'
]
==
'incorrect'
for
result
in
submit_results
):
elif
all
(
result
[
1
][
'status'
]
==
'incorrect'
for
result
in
submit_results
):
completed
=
'incorrect'
completed
=
Correctness
.
INCORRECT
else
:
else
:
completed
=
'partial'
completed
=
Correctness
.
PARTIAL
return
{
return
{
'message'
:
'Success!'
,
'message'
:
'Success!'
,
...
...
problem_builder/templates/html/mentoring_with_steps.html
View file @
6a45664a
{% load i18n %}
{% load i18n %}
<div
class=
"mentoring themed-xblock"
data-
step=
"{{ self.
step }}"
>
<div
class=
"mentoring themed-xblock"
data-
active-step=
"{{ self.active_
step }}"
>
{% if show_title and title %}
{% if show_title and title %}
<div
class=
"title"
>
<div
class=
"title"
>
...
@@ -8,7 +8,11 @@
...
@@ -8,7 +8,11 @@
{% endif %}
{% endif %}
<div
class=
"assessment-question-block"
>
<div
class=
"assessment-question-block"
>
{{child_content|safe}}
{% for child_content in children_contents %}
{{ child_content|safe }}
{% endfor %}
<div
class=
"submit"
>
<div
class=
"submit"
>
<span
class=
"assessment-checkmark fa icon-2x"
></span>
<span
class=
"assessment-checkmark fa icon-2x"
></span>
<input
type=
"button"
class=
"input-main"
value=
"Submit"
disabled=
"disabled"
/>
<input
type=
"button"
class=
"input-main"
value=
"Submit"
disabled=
"disabled"
/>
...
...
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