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
2105c1b3
Commit
2105c1b3
authored
Oct 19, 2015
by
Kelketek
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #76 from open-craft/empty_step
Enable seamless use of steps that have no questions.
parents
1326a0c8
c45a6019
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
115 additions
and
13 deletions
+115
-13
problem_builder/answer.py
+1
-0
problem_builder/public/js/mentoring_with_steps.js
+47
-12
problem_builder/public/js/step.js
+4
-0
problem_builder/questionnaire.py
+1
-0
problem_builder/step.py
+4
-0
problem_builder/templates/html/step.html
+1
-1
problem_builder/tests/integration/test_step_builder.py
+27
-0
problem_builder/tests/integration/xml_templates/step_builder.xml
+4
-0
problem_builder/tests/integration/xml_templates/step_builder_html_last.xml
+26
-0
No files found.
problem_builder/answer.py
View file @
2105c1b3
...
...
@@ -125,6 +125,7 @@ class AnswerBlock(SubmittingXBlockMixin, AnswerMixin, QuestionMixin, StudioEdita
"""
CATEGORY
=
'pb-answer'
STUDIO_LABEL
=
_
(
u"Long Answer"
)
answerable
=
True
name
=
String
(
display_name
=
_
(
"Question ID (name)"
),
...
...
problem_builder/public/js/mentoring_with_steps.js
View file @
2105c1b3
...
...
@@ -56,6 +56,15 @@ function MentoringWithStepsBlock(runtime, element) {
}
}
function
postUpdateStep
(
response
)
{
activeStep
=
response
.
active_step
;
if
(
activeStep
===
-
1
)
{
updateNumAttempts
();
}
else
{
updateControls
();
}
}
function
handleResults
(
response
)
{
showFeedback
(
response
);
...
...
@@ -64,14 +73,7 @@ function MentoringWithStepsBlock(runtime, element) {
// Otherwise, get UI ready for showing next step.
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'update_active_step'
);
$
.
post
(
handlerUrl
,
JSON
.
stringify
(
activeStep
+
1
))
.
success
(
function
(
response
)
{
activeStep
=
response
.
active_step
;
if
(
activeStep
===
-
1
)
{
updateNumAttempts
();
}
else
{
updateControls
();
}
});
.
success
(
postUpdateStep
);
}
function
updateNumAttempts
()
{
...
...
@@ -138,6 +140,14 @@ function MentoringWithStepsBlock(runtime, element) {
step
.
submit
(
handleResults
);
}
function
markRead
()
{
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'update_active_step'
);
$
.
post
(
handlerUrl
,
JSON
.
stringify
(
activeStep
+
1
)).
success
(
function
(
response
)
{
postUpdateStep
(
response
);
updateDisplay
();
});
}
function
getResults
()
{
var
step
=
steps
[
activeStep
];
step
.
getResults
(
handleReviewResults
);
...
...
@@ -195,9 +205,18 @@ function MentoringWithStepsBlock(runtime, element) {
showActiveStep
();
validateXBlock
();
updateNextLabel
();
nextDOM
.
attr
(
'disabled'
,
'disabled'
);
var
step
=
steps
[
activeStep
];
if
(
step
.
hasQuestion
())
{
nextDOM
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
nextDOM
.
removeAttr
(
'disabled'
);
}
if
(
isLastStep
()
&&
reviewStep
)
{
reviewDOM
.
attr
(
'disabled'
,
'disabled'
);
if
(
step
.
hasQuestion
())
{
reviewDOM
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
reviewDOM
.
removeAttr
(
'disabled'
)
}
reviewDOM
.
show
();
}
}
...
...
@@ -261,9 +280,14 @@ function MentoringWithStepsBlock(runtime, element) {
nextDOM
.
show
();
nextDOM
.
removeAttr
(
'disabled'
);
}
var
step
=
steps
[
activeStep
];
tryAgainDOM
.
hide
();
submitDOM
.
show
();
if
(
step
.
hasQuestion
())
{
submitDOM
.
show
();
}
else
{
submitDOM
.
hide
();
}
submitDOM
.
attr
(
'disabled'
,
'disabled'
);
reviewLinkDOM
.
show
();
...
...
@@ -302,8 +326,19 @@ function MentoringWithStepsBlock(runtime, element) {
}
else
{
submitDOM
.
removeAttr
(
'disabled'
);
}
if
(
isLastStep
())
{
if
(
isLastStep
()
&&
step
.
hasQuestion
()
)
{
nextDOM
.
hide
();
}
else
if
(
isLastStep
())
{
reviewDOM
.
one
(
'click'
,
markRead
);
reviewDOM
.
removeAttr
(
'disabled'
);
nextDOM
.
hide
()
}
else
if
(
!
step
.
hasQuestion
())
{
nextDOM
.
one
(
'click'
,
markRead
);
}
if
(
step
.
hasQuestion
())
{
submitDOM
.
show
();
}
else
{
submitDOM
.
hide
();
}
}
...
...
problem_builder/public/js/step.js
View file @
2105c1b3
...
...
@@ -85,6 +85,10 @@ function MentoringStepBlock(runtime, element) {
getStepLabel
:
function
()
{
return
$
(
'.sb-step'
,
element
).
data
(
'next-button-label'
);
},
hasQuestion
:
function
()
{
return
$
(
'.sb-step'
,
element
).
data
(
'has-question'
)
}
};
...
...
problem_builder/questionnaire.py
View file @
2105c1b3
...
...
@@ -90,6 +90,7 @@ class QuestionnaireAbstractBlock(
)
editable_fields
=
(
'question'
,
'message'
,
'weight'
,
'display_name'
,
'show_title'
)
has_children
=
True
answerable
=
True
@lazy
def
html_id
(
self
):
...
...
problem_builder/step.py
View file @
2105c1b3
...
...
@@ -133,6 +133,10 @@ class MentoringStepBlock(
AnswerRecapBlock
,
MentoringTableBlock
,
]
@property
def
has_question
(
self
):
return
any
(
getattr
(
child
,
'answerable'
,
False
)
for
child
in
self
.
steps
)
@XBlock.json_handler
def
submit
(
self
,
submissions
,
suffix
=
''
):
log
.
info
(
u'Received submissions: {}'
.
format
(
submissions
))
...
...
problem_builder/templates/html/step.html
View file @
2105c1b3
<div
class=
"sb-step"
data-next-button-label=
"{{ self.next_button_label }}"
>
<div
class=
"sb-step"
data-next-button-label=
"{{ self.next_button_label }}"
{%
if
self
.
has_question
%}
data-has-question=
"true"
{%
endif
%}
>
{% if show_title %}
<div
class=
"title"
>
<h3>
...
...
problem_builder/tests/integration/test_step_builder.py
View file @
2105c1b3
...
...
@@ -211,6 +211,7 @@ class StepBuilderTest(MentoringAssessmentBaseTest):
# It should be possible to visit the MRQ from here
self
.
wait_until_clickable
(
controls
.
next_question
)
controls
.
next_question
.
click
()
self
.
html_section
(
step_builder
,
controls
)
self
.
peek_at_multiple_response_question
(
None
,
step_builder
,
controls
,
extended_feedback
=
True
,
alternative_review
=
True
)
...
...
@@ -230,6 +231,24 @@ class StepBuilderTest(MentoringAssessmentBaseTest):
self
.
expect_question_visible
(
None
,
step_builder
)
self
.
assertEqual
(
controls
.
next_question
.
get_attribute
(
'value'
),
"Next Challenge"
)
def
html_section
(
self
,
step_builder
,
controls
,
last
=
False
):
self
.
wait_until_hidden
(
controls
.
submit
)
target_control
=
controls
.
review
if
last
else
controls
.
next_question
self
.
wait_until_clickable
(
target_control
)
target_control
.
click
()
def
test_html_last
(
self
):
step_builder
,
controls
=
self
.
load_assessment_scenario
(
"step_builder_html_last.xml"
)
# Step 1
# Submit free-form answer, go to next step
self
.
freeform_answer
(
None
,
step_builder
,
controls
,
'This is the answer'
,
CORRECT
)
# Step 2
# Submit MCQ, go to next step
self
.
single_choice_question
(
None
,
step_builder
,
controls
,
'Maybe not'
,
INCORRECT
)
self
.
html_section
(
step_builder
,
controls
,
last
=
True
)
@data
(
{
"max_attempts"
:
0
,
"extended_feedback"
:
False
},
# Unlimited attempts, no extended feedback
{
"max_attempts"
:
1
,
"extended_feedback"
:
True
},
# Limited attempts, extended feedback
...
...
@@ -253,6 +272,9 @@ class StepBuilderTest(MentoringAssessmentBaseTest):
# Submit rating, go to next step
self
.
rating_question
(
None
,
step_builder
,
controls
,
"5 - Extremely good"
,
CORRECT
)
# Step 4, html with no question.
self
.
html_section
(
step_builder
,
controls
)
# Last step
# Submit MRQ, go to review
with
patch
.
object
(
WorkbenchRuntime
,
'publish'
)
as
patched_method
:
...
...
@@ -308,6 +330,8 @@ class StepBuilderTest(MentoringAssessmentBaseTest):
# Submit rating, go to next step
self
.
rating_question
(
None
,
step_builder
,
controls
,
"1 - Not good at all"
,
INCORRECT
)
# Step 4, read only. Go to next step.
self
.
html_section
(
step_builder
,
controls
)
# Last step
# Submit MRQ, go to review
user_selection
=
(
"Its elegance"
,
"Its beauty"
,
"Its gracefulness"
)
...
...
@@ -350,6 +374,7 @@ class StepBuilderTest(MentoringAssessmentBaseTest):
self
.
freeform_answer
(
None
,
step_builder
,
controls
,
'This is the answer'
,
CORRECT
)
self
.
single_choice_question
(
None
,
step_builder
,
controls
,
'Maybe not'
,
INCORRECT
)
self
.
rating_question
(
None
,
step_builder
,
controls
,
"5 - Extremely good"
,
CORRECT
)
self
.
html_section
(
step_builder
,
controls
)
self
.
multiple_response_question
(
None
,
step_builder
,
controls
,
(
"Its beauty"
,),
PARTIAL
,
last
=
True
)
# The review tips for MCQ 2 and the MRQ should be shown:
...
...
@@ -374,6 +399,7 @@ class StepBuilderTest(MentoringAssessmentBaseTest):
self
.
single_choice_question
(
None
,
step_builder
,
controls
,
'Yes'
,
CORRECT
)
self
.
rating_question
(
None
,
step_builder
,
controls
,
"5 - Extremely good"
,
CORRECT
)
user_selection
=
(
"Its elegance"
,
"Its beauty"
,
"Its gracefulness"
)
self
.
html_section
(
step_builder
,
controls
)
self
.
multiple_response_question
(
None
,
step_builder
,
controls
,
user_selection
,
CORRECT
,
last
=
True
)
# If attempts remain and student got all answers right, show "complete" message
...
...
@@ -390,6 +416,7 @@ class StepBuilderTest(MentoringAssessmentBaseTest):
)
self
.
single_choice_question
(
None
,
step_builder
,
controls
,
'Maybe not'
,
INCORRECT
)
self
.
rating_question
(
None
,
step_builder
,
controls
,
"1 - Not good at all"
,
INCORRECT
)
self
.
html_section
(
step_builder
,
controls
)
self
.
multiple_response_question
(
None
,
step_builder
,
controls
,
(
"Its beauty"
,),
PARTIAL
,
last
=
True
)
# The review tips will not be shown because no attempts remain:
...
...
problem_builder/tests/integration/xml_templates/step_builder.xml
View file @
2105c1b3
...
...
@@ -36,6 +36,10 @@
</pb-rating>
</sb-step>
<sb-step
display_name=
"Fourth Step"
>
<html_demo>
Test test test
</html_demo>
</sb-step>
<sb-step
display_name=
"Last step"
>
<pb-mrq
name=
"mrq_1_1"
question=
"What do you like in this MRQ?"
required_choices=
'["gracefulness","elegance","beauty"]'
message=
"Question Feedback Message"
>
<pb-choice
value=
"elegance"
>
Its elegance
</pb-choice>
...
...
problem_builder/tests/integration/xml_templates/step_builder_html_last.xml
0 → 100644
View file @
2105c1b3
<step-builder
url_name=
"step-builder"
display_name=
"Step Builder"
max_attempts=
"1"
extended_feedback=
"True"
>
<sb-step
display_name=
"First step"
next_button_label=
"Next Challenge"
>
<pb-answer
name=
"goal"
question=
"What is your goal?"
/>
</sb-step>
<sb-step
display_name=
"Second step"
next_button_label=
"Next Item"
>
<pb-mcq
name=
"mcq_1_1"
question=
"Do you like this MCQ?"
correct_choices=
'["yes"]'
>
<pb-choice
value=
"yes"
>
Yes
</pb-choice>
<pb-choice
value=
"maybenot"
>
Maybe not
</pb-choice>
<pb-choice
value=
"understand"
>
I don't understand
</pb-choice>
<pb-tip
values=
'["yes"]'
>
Great!
</pb-tip>
<pb-tip
values=
'["maybenot"]'
>
Ah, damn.
</pb-tip>
<pb-tip
values=
'["understand"]'
><div
id=
"test-custom-html"
>
Really?
</div></pb-tip>
</pb-mcq>
</sb-step>
<sb-step
display_name=
"Last HTML step"
>
<html_demo>
Bla bla bla
</html_demo>
</sb-step>
<sb-review-step
/>
</step-builder>
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