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
e89db114
Commit
e89db114
authored
Nov 22, 2016
by
Tim Krones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add completion block.
parent
94bd72c3
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
197 additions
and
2 deletions
+197
-2
problem_builder/completion.py
+135
-0
problem_builder/mentoring.py
+2
-1
problem_builder/public/js/completion.js
+40
-0
problem_builder/step.py
+2
-1
problem_builder/templates/html/completion.html
+17
-0
setup.py
+1
-0
No files found.
problem_builder/completion.py
0 → 100644
View file @
e89db114
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2015 Harvard, edX & OpenCraft
#
# This software's license gives you freedom; you can copy, convey,
# propagate, redistribute and/or modify this program under the terms of
# the GNU Affero General Public License (AGPL) as published by the Free
# Software Foundation (FSF), either version 3 of the License, or (at your
# option) any later version of the AGPL published by the FSF.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program in a file in the toplevel directory called
# "AGPLv3". If not, see <http://www.gnu.org/licenses/>.
#
# Imports ###########################################################
import
logging
from
xblock.core
import
XBlock
from
xblock.fields
import
Scope
,
String
,
Boolean
from
xblock.fragment
import
Fragment
from
xblockutils.studio_editable
import
StudioEditableXBlockMixin
from
xblockutils.resources
import
ResourceLoader
from
.mixins
import
QuestionMixin
,
XBlockWithTranslationServiceMixin
from
.sub_api
import
sub_api
,
SubmittingXBlockMixin
# Globals ###########################################################
log
=
logging
.
getLogger
(
__name__
)
loader
=
ResourceLoader
(
__name__
)
# Make '_' a no-op so we can scrape strings
def
_
(
text
):
return
text
# Classes ###########################################################
@XBlock.needs
(
'i18n'
)
class
CompletionBlock
(
SubmittingXBlockMixin
,
QuestionMixin
,
StudioEditableXBlockMixin
,
XBlockWithTranslationServiceMixin
,
XBlock
):
"""
An XBlock used by students to indicate that they completed a given task.
The student's answer is always considered "correct".
"""
CATEGORY
=
'pb-completion'
STUDIO_LABEL
=
_
(
u'Completion'
)
answerable
=
True
question
=
String
(
display_name
=
_
(
'Question'
),
help
=
_
(
'Mentions a specific activity and asks the student whether they completed it.'
),
scope
=
Scope
.
content
,
default
=
_
(
'Please indicate whether you attended the In Person Workshop session by (un-)checking the option below.'
),
)
answer
=
String
(
display_name
=
_
(
'Answer'
),
help
=
_
(
'Represents the answer that the student can (un-)check '
'to indicate whether they completed the activity that the question mentions.'
),
scope
=
Scope
.
content
,
default
=
_
(
'Yes, I attended the session.'
),
)
student_value
=
Boolean
(
help
=
_
(
"Records student's answer."
),
scope
=
Scope
.
user_state
,
default
=
None
,
)
editable_fields
=
(
'display_name'
,
'show_title'
,
'question'
,
'answer'
)
def
mentoring_view
(
self
,
context
):
"""
Main view of this block.
"""
context
=
context
.
copy
()
if
context
else
{}
context
[
'question'
]
=
self
.
question
context
[
'answer'
]
=
self
.
answer
context
[
'checked'
]
=
self
.
student_value
if
self
.
student_value
is
not
None
else
False
context
[
'title'
]
=
self
.
display_name_with_default
context
[
'hide_header'
]
=
context
.
get
(
'hide_header'
,
False
)
or
not
self
.
show_title
html
=
loader
.
render_template
(
'templates/html/completion.html'
,
context
)
fragment
=
Fragment
(
html
)
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/js/completion.js'
))
fragment
.
initialize_js
(
'CompletionBlock'
)
return
fragment
student_view
=
mentoring_view
preview_view
=
mentoring_view
def
get_last_result
(
self
):
""" Return the current/last result in the required format """
if
self
.
student_value
is
None
:
return
{}
return
{
'submission'
:
self
.
student_value
,
'status'
:
'correct'
,
'tips'
:
[],
'weight'
:
self
.
weight
,
'score'
:
1
,
}
def
get_results
(
self
):
""" Alias for get_last_result() """
return
self
.
get_last_result
()
def
submit
(
self
,
value
):
"""
Persist answer submitted by student.
"""
log
.
debug
(
u'Received Completion submission: "
%
s"'
,
value
)
self
.
student_value
=
value
if
sub_api
:
# Also send to the submissions API:
sub_api
.
create_submission
(
self
.
student_item_key
,
value
)
result
=
self
.
get_last_result
()
log
.
debug
(
u'Completion submission result:
%
s'
,
result
)
return
result
problem_builder/mentoring.py
View file @
e89db114
...
...
@@ -48,6 +48,7 @@ from xblockutils.studio_editable import (
)
from
problem_builder.answer
import
AnswerBlock
,
AnswerRecapBlock
from
problem_builder.completion
import
CompletionBlock
from
problem_builder.mcq
import
MCQBlock
,
RatingBlock
from
problem_builder.mrq
import
MRQBlock
from
problem_builder.plot
import
PlotBlock
...
...
@@ -381,7 +382,7 @@ class MentoringBlock(BaseMentoringBlock, StudioContainerWithNestedXBlocksMixin,
return
[
NestedXBlockSpec
(
AnswerBlock
,
boilerplate
=
'studio_default'
),
MCQBlock
,
RatingBlock
,
MRQBlock
,
MCQBlock
,
RatingBlock
,
MRQBlock
,
CompletionBlock
,
NestedXBlockSpec
(
None
,
category
=
"html"
,
label
=
self
.
_
(
"HTML"
)),
AnswerRecapBlock
,
MentoringTableBlock
,
PlotBlock
,
SliderBlock
]
+
additional_blocks
+
message_block_shims
...
...
problem_builder/public/js/completion.js
0 → 100644
View file @
e89db114
function
CompletionBlock
(
runtime
,
element
)
{
var
$completion
=
$
(
'.pb-completion-value'
);
return
{
mode
:
null
,
mentoring
:
null
,
init
:
function
(
options
)
{
this
.
mode
=
options
.
mode
;
this
.
mentoring
=
options
.
mentoring
;
$completion
.
on
(
'change'
,
options
.
onChange
);
},
submit
:
function
()
{
return
$completion
.
is
(
':checked'
);
},
handleSubmit
:
function
(
result
)
{
if
(
typeof
result
.
submission
!==
'undefined'
)
{
this
.
updateCompletion
(
result
);
$
(
'.submit-result'
,
element
).
css
(
'visibility'
,
'visible'
);
}
},
handleReview
:
function
(
result
)
{
this
.
updateCompletion
(
result
);
$completion
.
prop
(
'disabled'
,
true
);
},
clearResult
:
function
()
{
$
(
'.submit-result'
,
element
).
css
(
'visibility'
,
'hidden'
);
},
updateCompletion
:
function
(
result
)
{
$completion
.
prop
(
'checked'
,
result
.
submission
);
}
};
}
problem_builder/step.py
View file @
e89db114
...
...
@@ -31,6 +31,7 @@ from xblockutils.studio_editable import (
)
from
problem_builder.answer
import
AnswerBlock
,
AnswerRecapBlock
from
problem_builder.completion
import
CompletionBlock
from
problem_builder.mcq
import
MCQBlock
,
RatingBlock
from
problem_builder.mixins
import
EnumerableChildMixin
,
StepParentMixin
from
problem_builder.mrq
import
MRQBlock
...
...
@@ -144,7 +145,7 @@ class MentoringStepBlock(
return
[
NestedXBlockSpec
(
AnswerBlock
,
boilerplate
=
'studio_default'
),
MCQBlock
,
RatingBlock
,
MRQBlock
,
MCQBlock
,
RatingBlock
,
MRQBlock
,
CompletionBlock
,
NestedXBlockSpec
(
None
,
category
=
"html"
,
label
=
self
.
_
(
"HTML"
)),
AnswerRecapBlock
,
MentoringTableBlock
,
PlotBlock
,
SliderBlock
]
+
additional_blocks
...
...
problem_builder/templates/html/completion.html
0 → 100644
View file @
e89db114
{% load i18n %}
<div
class=
"xblock-pb-completion"
>
{% if not hide_header %}
<h3
class=
"question-title"
>
{{ title }}
</h3>
{% endif %}
<div
class=
"clearfix"
>
<p>
{{ question|safe }}
</p>
<p>
<label>
<input
type=
"checkbox"
class=
"pb-completion-value"
{%
if
checked
%}
checked=
"checked"
{%
endif
%}
/>
{{ answer|safe }}
</label>
</p>
</div>
<div
class=
"clearfix"
>
<span
class=
"submit-result fa icon-2x checkmark-correct icon-ok fa-check"
style=
"visibility: hidden;"
aria-label=
"{% trans "
Complete
"
%}"
></span>
</div>
</div>
setup.py
View file @
e89db114
...
...
@@ -59,6 +59,7 @@ BLOCKS = [
'pb-rating = problem_builder.mcq:RatingBlock'
,
'pb-mrq = problem_builder.mrq:MRQBlock'
,
'pb-slider = problem_builder.slider:SliderBlock'
,
'pb-completion = problem_builder.completion:CompletionBlock'
,
'pb-message = problem_builder.message:MentoringMessageBlock'
,
'pb-tip = problem_builder.tip:TipBlock'
,
'pb-choice = problem_builder.choice:ChoiceBlock'
,
...
...
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