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
02fa6d72
Commit
02fa6d72
authored
Dec 23, 2014
by
E. Kolpakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added ability to use HTML LightChild in question blocks
parent
850080ed
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
91 additions
and
9 deletions
+91
-9
mentoring/choice.py
+14
-0
mentoring/html.py
+2
-1
mentoring/public/css/questionnaire.css
+10
-0
mentoring/questionnaire.py
+2
-2
mentoring/templates/html/choice.html
+7
-0
mentoring/templates/html/mcqblock_choices.html
+2
-1
mentoring/templates/html/mcqblock_rating.html
+3
-1
mentoring/templates/html/mrqblock_choices.html
+1
-1
mentoring/utils.py
+5
-0
tests/integration/test_answer.py
+3
-3
tests/integration/test_mcq.py
+18
-0
tests/integration/xml/mrq_with_html_choices.xml
+24
-0
No files found.
mentoring/choice.py
View file @
02fa6d72
...
...
@@ -26,6 +26,7 @@
import
logging
from
.light_children
import
LightChild
,
Scope
,
String
from
.utils
import
loader
,
ContextConstants
# Globals ###########################################################
...
...
@@ -41,3 +42,16 @@ class ChoiceBlock(LightChild):
"""
value
=
String
(
help
=
"Value of the choice when selected"
,
scope
=
Scope
.
content
,
default
=
""
)
content
=
String
(
help
=
"Human-readable version of the choice value"
,
scope
=
Scope
.
content
,
default
=
""
)
has_children
=
True
def
render
(
self
):
# return self.content
"""
Returns a fragment containing the formatted tip
"""
fragment
,
named_children
=
self
.
get_children_fragment
({
ContextConstants
.
AS_TEMPLATE
:
False
})
fragment
.
add_content
(
loader
.
render_template
(
'templates/html/choice.html'
,
{
'self'
:
self
,
'named_children'
:
named_children
,
}))
return
self
.
xblock_container
.
fragment_text_rewriting
(
fragment
)
mentoring/html.py
View file @
02fa6d72
...
...
@@ -33,6 +33,7 @@ from .light_children import LightChild, Scope, String
# Globals ###########################################################
from
.utils
import
ContextConstants
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -56,7 +57,7 @@ class HTMLBlock(LightChild):
return
block
def
student_view
(
self
,
context
=
None
):
as_template
=
context
.
get
(
'as_template'
,
True
)
if
context
is
not
None
else
True
as_template
=
context
.
get
(
ContextConstants
.
AS_TEMPLATE
,
True
)
if
context
is
not
None
else
True
if
as_template
:
return
Fragment
(
u"<script type='text/template' id='{}'>
\n
{}
\n
</script>"
.
format
(
'light-child-template'
,
...
...
mentoring/public/css/questionnaire.css
View file @
02fa6d72
...
...
@@ -80,3 +80,13 @@
text-indent
:
-22px
;
line-height
:
1.3
;
}
.mentoring
.choices-list
.choice-text
>
div
.xblock-light-child
,
.mentoring
.choices-list
.choice-text
>
div
.xblock-light-child
>
div
{
/*
HTML Light Child content is wrapped in two divs: div.xblock-light-child and just div
On the other hand, choice are usually rendered inline.
Hence, we render first two divs inline, than all the actual content of HTML is rendered as is
*/
display
:
inline
;
}
mentoring/questionnaire.py
View file @
02fa6d72
...
...
@@ -31,7 +31,7 @@ from .choice import ChoiceBlock
from
.step
import
StepMixin
from
.light_children
import
LightChild
,
Scope
,
String
,
Float
from
.tip
import
TipBlock
from
.utils
import
loader
from
.utils
import
loader
,
ContextConstants
# Globals ###########################################################
...
...
@@ -75,7 +75,7 @@ class QuestionnaireAbstractBlock(LightChild, StepMixin):
def
student_view
(
self
,
context
=
None
):
name
=
self
.
__class__
.
__name__
as_template
=
context
.
get
(
'as_template'
,
True
)
if
context
is
not
None
else
True
as_template
=
context
.
get
(
ContextConstants
.
AS_TEMPLATE
,
True
)
if
context
is
not
None
else
True
if
str
(
self
.
type
)
not
in
self
.
valid_types
:
raise
ValueError
(
u'Invalid value for {}.type: `{}`'
.
format
(
name
,
self
.
type
))
...
...
mentoring/templates/html/choice.html
0 → 100644
View file @
02fa6d72
<span
class=
"choice-text"
>
{% if self.content %}{{ self.content }}{% endif %}
{% for name, c in named_children %}
{{c.body_html|safe}}
{% endfor %}
</span>
\ No newline at end of file
mentoring/templates/html/mcqblock_choices.html
View file @
02fa6d72
...
...
@@ -8,7 +8,8 @@
<div
class=
"choice"
>
<div
class=
"choice-result fa icon-2x"
></div>
<label
class=
"choice-label"
>
<input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"{{ choice.value }}"
{%
if
self
.
student_choice =
=
choice
.
value
%}
checked
{%
endif
%}
/>
{{ choice.content }}
<input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"{{ choice.value }}"
{%
if
self
.
student_choice =
=
choice
.
value
%}
checked
{%
endif
%}
/>
{{ choice.render.body_html|safe }}
</label>
<div
class=
"choice-tips"
></div>
</div>
...
...
mentoring/templates/html/mcqblock_rating.html
View file @
02fa6d72
...
...
@@ -34,7 +34,9 @@
{% for choice in custom_choices %}
<div
class=
"choice"
>
<div
class=
"choice-result fa icon-2x"
></div>
<label><input
type=
"radio"
name=
"{{ self.name }}"
value=
"{{ choice.value }}"
{%
if
self
.
student_choice =
=
'{{
choice
.
value
}}'
%}
checked
{%
endif
%}
/>
{{ choice.content }}
</label>
<label><input
type=
"radio"
name=
"{{ self.name }}"
value=
"{{ choice.value }}"
{%
if
self
.
student_choice =
=
'{{
choice
.
value
}}'
%}
checked
{%
endif
%}
/>
{{ choice.render.body_html|safe }}
</label>
<div
class=
"choice-tips"
></div>
</div>
{% endfor %}
...
...
mentoring/templates/html/mrqblock_choices.html
View file @
02fa6d72
...
...
@@ -11,7 +11,7 @@
<input
class=
"choice-selector"
type=
"checkbox"
name=
"{{ self.name }}"
value=
"{{ choice.value }}"
{%
if
choice
.
value
in
self
.
student_choices
%}
checked
{%
endif
%}
/>
{{ choice.
content
}}
{{ choice.
render.body_html|safe
}}
</label>
<div
class=
"choice-tips"
></div>
</div>
...
...
mentoring/utils.py
View file @
02fa6d72
...
...
@@ -89,3 +89,7 @@ class XBlockWithChildrenFragmentsMixin(object):
for
name
,
child_fragment
in
named_children
:
fragment
.
add_content
(
child_fragment
.
content
)
return
fragment
class
ContextConstants
(
object
):
AS_TEMPLATE
=
'as_template'
\ No newline at end of file
tests/integration/test_answer.py
View file @
02fa6d72
...
...
@@ -36,7 +36,7 @@ class AnswerBlockTest(MentoringBaseTest):
# Answer should initially be blank on all instances with the same answer name
mentoring
=
self
.
go_to_page
(
'Answer Edit 2'
)
answer1_bis
=
mentoring
.
find_element_by_css_selector
(
'
.xblock
textarea'
)
answer1_bis
=
mentoring
.
find_element_by_css_selector
(
'textarea'
)
answer1_readonly
=
mentoring
.
find_element_by_css_selector
(
'blockquote.answer.read_only'
)
self
.
assertEqual
(
answer1_bis
.
get_attribute
(
'value'
),
''
)
self
.
assertEqual
(
answer1_readonly
.
text
,
''
)
...
...
@@ -47,7 +47,7 @@ class AnswerBlockTest(MentoringBaseTest):
self
.
assertEqual
(
header1
.
text
,
'XBlock: Answer Edit 1'
)
# Check <html> child
p
=
mentoring
.
find_element_by_css_selector
(
'
div.xblock
p'
)
p
=
mentoring
.
find_element_by_css_selector
(
'p'
)
self
.
assertEqual
(
p
.
text
,
'This should be displayed in the answer_edit scenario'
)
# Initial unsubmitted text
...
...
@@ -77,7 +77,7 @@ class AnswerBlockTest(MentoringBaseTest):
# Answer content should show on a different instance with the same name
mentoring
=
self
.
go_to_page
(
'Answer Edit 2'
)
answer1_bis
=
mentoring
.
find_element_by_css_selector
(
'
.xblock
textarea'
)
answer1_bis
=
mentoring
.
find_element_by_css_selector
(
'textarea'
)
answer1_readonly
=
mentoring
.
find_element_by_css_selector
(
'blockquote.answer.read_only'
)
self
.
assertEqual
(
answer1_bis
.
get_attribute
(
'value'
),
'This is the answer. It has a second statement.'
)
self
.
assertEqual
(
answer1_readonly
.
text
,
'This is the answer. It has a second statement.'
)
...
...
tests/integration/test_mcq.py
View file @
02fa6d72
...
...
@@ -183,3 +183,21 @@ class MCQBlockTest(MentoringBaseTest):
mentoring
.
click
()
self
.
assertFalse
(
item_feedback_popup
.
is_displayed
())
def
test_mcq_html_choices
(
self
):
mentoring
=
self
.
go_to_page
(
'Mrq With Html Choices'
)
choices_list
=
mentoring
.
find_element_by_css_selector
(
".choices-list"
)
contents
=
[
"<b>Its elegance</b>"
,
"<i>Its beauty</i>"
,
"<strong>Its gracefulness</strong>"
,
'<span style="font-color:red">Its bugs</span>'
]
for
index
,
expected_content
in
enumerate
(
contents
):
choice_wrapper
=
choices_list
.
find_elements_by_css_selector
(
".choice"
)[
index
]
choice_label
=
choice_wrapper
.
find_element_by_css_selector
(
".choice-label .choice-text"
)
light_child
=
choice_label
.
find_element_by_css_selector
(
".xblock-light-child"
)
content
=
light_child
.
find_element_by_css_selector
(
"div"
)
.
get_attribute
(
'innerHTML'
)
self
.
assertEqual
(
content
,
expected_content
)
tests/integration/xml/mrq_with_html_choices.xml
0 → 100644
View file @
02fa6d72
<vertical_demo>
<mentoring
url_name=
"mcq_with_comments"
display_name=
"MRQ Exercise 7"
weight=
"1"
enforce_dependency=
"false"
>
<title>
MRQ With Resizable popups
</title>
<mrq
name=
"mrq_1_1_7"
type=
"choices"
>
<question>
What do you like in this MRQ?
</question>
<choice
value=
"elegance"
><html><b>
Its elegance
</b></html></choice>
<choice
value=
"beauty"
><html><i>
Its beauty
</i></html></choice>
<choice
value=
"gracefulness"
><html><strong>
Its gracefulness
</strong></html></choice>
<choice
value=
"bugs"
><html><span
style=
"font-color:red"
>
Its bugs
</span></html></choice>
<tip
require=
"gracefulness"
width =
"200"
height =
"200"
>
This MRQ is indeed very graceful
</tip>
<tip
require=
"elegance"
width =
"600"
height =
"800"
>
This is something everyone has to like about this MRQ
</tip>
<tip
require=
"beauty"
width =
"400"
height =
"600"
>
This is something everyone has to like about beauty
</tip>
<tip
reject=
"bugs"
width =
"100"
height =
"200"
>
Nah, there isn\'t any!
</tip>
</mrq>
<message
type=
"completed"
>
<html><p>
Congratulations!
</p></html>
</message>
<message
type=
"incomplete"
>
<html><p>
Still some work to do...
</p></html>
</message>
</mentoring>
</vertical_demo>
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