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
dfb4cea9
Commit
dfb4cea9
authored
Mar 31, 2015
by
Xavier Antoviaque
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9 from open-craft/mtyaka/tip-styles
Redesigned tooltips for LMS theme.
parents
09d8dbd7
2d785c99
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
180 additions
and
40 deletions
+180
-40
mentoring/public/js/mentoring.js
+1
-0
mentoring/public/js/questionnaire.js
+15
-3
mentoring/public/themes/lms.css
+89
-0
mentoring/templates/html/mcqblock.html
+3
-1
mentoring/templates/html/mrqblock.html
+3
-1
mentoring/templates/html/ratingblock.html
+25
-29
mentoring/tests/integration/test_mcq.py
+44
-6
No files found.
mentoring/public/js/mentoring.js
View file @
dfb4cea9
...
...
@@ -52,6 +52,7 @@ function MentoringBlock(runtime, element) {
if
(
!
clickedInside
(
item_feedback_selector
,
item_feedback_parent_selector
))
{
$
(
item_feedback_selector
).
not
(
':hidden'
).
hide
();
$
(
'.choice-tips-container'
).
removeClass
(
'with-tips'
);
}
});
...
...
mentoring/public/js/questionnaire.js
View file @
dfb4cea9
...
...
@@ -3,7 +3,9 @@
function
MessageView
(
element
,
mentoring
)
{
return
{
messageDOM
:
$
(
'.feedback'
,
element
),
allChoicesDOM
:
$
(
'.choice'
,
element
),
allPopupsDOM
:
$
(
'.choice-tips, .feedback'
,
element
),
allPopupContainersDOM
:
$
(
'.choice-tips-container'
,
element
),
allResultsDOM
:
$
(
'.choice-result'
,
element
),
clearPopupEvents
:
function
()
{
this
.
allPopupsDOM
.
hide
();
...
...
@@ -28,6 +30,11 @@ function MessageView(element, mentoring) {
popupDOM
.
css
(
'height'
,
''
);
}
var
container
=
popupDOM
.
parent
(
'.choice-tips-container'
);
if
(
container
.
length
)
{
this
.
allPopupContainersDOM
.
addClass
(
'with-tips'
).
removeClass
(
'active'
);
container
.
addClass
(
'active'
);
}
popupDOM
.
show
();
mentoring
.
publish_event
({
...
...
@@ -53,6 +60,8 @@ function MessageView(element, mentoring) {
}
},
clearResult
:
function
()
{
this
.
allPopupContainersDOM
.
removeClass
(
'with-tips active'
);
this
.
allChoicesDOM
.
removeClass
(
'correct incorrect'
);
this
.
allPopupsDOM
.
html
(
''
).
hide
();
this
.
allResultsDOM
.
removeClass
(
'checkmark-incorrect icon-exclamation fa-exclamation checkmark-correct icon-ok fa-check'
...
...
@@ -85,6 +94,7 @@ function MCQBlock(runtime, element) {
if
(
this
.
mode
===
'assessment'
)
return
;
mentoring
=
this
.
mentoring
;
var
messageView
=
MessageView
(
element
,
mentoring
);
...
...
@@ -99,14 +109,17 @@ function MCQBlock(runtime, element) {
var
choiceTipsCloseDOM
;
if
(
result
.
status
===
"correct"
&&
choiceInputDOM
.
val
()
===
result
.
submission
)
{
choiceDOM
.
addClass
(
'correct'
);
choiceResultDOM
.
addClass
(
'checkmark-correct icon-ok fa-check'
);
}
else
if
(
choiceInputDOM
.
val
()
===
result
.
submission
||
_
.
isNull
(
result
.
submission
))
{
choiceDOM
.
addClass
(
'incorrect'
);
choiceResultDOM
.
addClass
(
'checkmark-incorrect icon-exclamation fa-exclamation'
);
}
if
(
result
.
tips
&&
choiceInputDOM
.
val
()
===
result
.
submission
)
{
mentoring
.
setContent
(
choiceTipsDOM
,
result
.
tips
);
messageView
.
showMessage
(
choiceTipsDOM
);
}
choiceTipsCloseDOM
=
$
(
'.close'
,
choiceTipsDOM
);
...
...
@@ -121,9 +134,6 @@ function MCQBlock(runtime, element) {
messageView
.
showMessage
(
'<div class="message-content">You have not provided an answer.</div>'
+
'<div class="close icon-remove-sign fa-times-circle"></div>'
);
}
else
if
(
result
.
tips
)
{
messageView
.
showMessage
(
result
.
tips
);
}
},
clearResult
:
function
()
{
...
...
@@ -189,8 +199,10 @@ function MRQBlock(runtime, element) {
if
(
!
hide_results
&&
(
result
.
completed
||
choiceInputDOM
.
prop
(
'checked'
)
||
options
.
max_attempts
<=
0
))
{
if
(
choice
.
completed
)
{
choiceDOM
.
addClass
(
'correct'
);
choiceResultDOM
.
addClass
(
'checkmark-correct icon-ok fa-check'
);
}
else
if
(
!
choice
.
completed
)
{
choiceDOM
.
addClass
(
'incorrect'
);
choiceResultDOM
.
addClass
(
'checkmark-incorrect icon-exclamation fa-exclamation'
);
}
...
...
mentoring/public/themes/lms.css
View file @
dfb4cea9
.themed-xblock.mentoring
.questionnaire
.choice-result
{
display
:
table-cell
;
}
.themed-xblock.mentoring
.choice-result
::before
{
content
:
""
;
display
:
block
;
width
:
36px
;
}
.themed-xblock.mentoring
.checkmark-incorrect
{
color
:
#c1373f
;
}
.themed-xblock.mentoring
.checkmark-correct
::before
{
content
:
"\f00c"
;
}
.themed-xblock.mentoring
.checkmark-incorrect
::before
{
content
:
"\f00d"
;
}
...
...
@@ -15,4 +29,78 @@
div
.course-wrapper
section
.course-content
.themed-xblock.mentoring
p
:empty
{
display
:
block
;
margin-bottom
:
1.41575em
;
}
.themed-xblock.mentoring
.choices-list
{
display
:
table
;
width
:
100%
;
border-spacing
:
0
;
}
.themed-xblock.mentoring
.choice-label
{
display
:
table-cell
;
vertical-align
:
middle
;
width
:
100%
;
padding-bottom
:
10px
;
padding-top
:
2px
;
}
.themed-xblock.mentoring
.choice-label
span
.low
{
line-height
:
inherit
;
}
.themed-xblock.mentoring
.choice-result
,
.themed-xblock.mentoring
.choice-label
,
.themed-xblock.mentoring
.choice-tips-container
{
vertical-align
:
top
;
}
.themed-xblock.mentoring
.choice-tips
{
position
:
relative
;
}
.themed-xblock.mentoring
.questionnaire
.choice
{
display
:
table-row
;
}
.themed-xblock.mentoring
.questionnaire
.feedback
{
min-height
:
100%
;
border-left
:
2px
solid
#ddd
;
}
.themed-xblock.mentoring
.questionnaire
.choice-tips
,
.themed-xblock.mentoring
.questionnaire
.feedback
{
color
:
#3c3c3c
;
background
:
transparent
;
font-family
:
inherit
;
font-size
:
inherit
;
opacity
:
1
;
padding
:
0
20px
;
}
.themed-xblock.mentoring
.questionnaire
.choice-tips-container
{
display
:
table-cell
;
}
.themed-xblock.mentoring
.questionnaire
.choice-tips
p
,
.themed-xblock.mentoring
.questionnaire
.feedback
p
{
color
:
#3c3c3c
;
}
.themed-xblock.mentoring
.questionnaire
.choice-tips
.close
,
.themed-xblock.mentoring
.questionnaire
.feedback
.close
{
display
:
none
;
}
.themed-xblock.mentoring
.choice
.choice-tips-container.with-tips
{
border-left
:
2px
solid
#ddd
;
}
.themed-xblock.mentoring
.choice.correct
.choice-tips-container.active
{
border-color
:
#629b2b
;
}
.themed-xblock.mentoring
.choice.incorrect
.choice-tips-container.active
{
border-color
:
#c1373f
;
}
\ No newline at end of file
mentoring/templates/html/mcqblock.html
View file @
dfb4cea9
...
...
@@ -11,7 +11,9 @@
<input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"{{ choice.value }}"
{%
if
self
.
student_choice =
=
choice
.
value
%}
checked
{%
endif
%}
/>
<span
class=
"choice-text"
>
{{ choice.content|safe }}
</span>
</label>
<div
class=
"choice-tips"
></div>
<div
class=
"choice-tips-container"
>
<div
class=
"choice-tips"
></div>
</div>
</div>
{% endfor %}
<div
class=
"feedback"
></div>
...
...
mentoring/templates/html/mrqblock.html
View file @
dfb4cea9
...
...
@@ -13,7 +13,9 @@
{%
if
choice
.
value
in
self
.
student_choices
%}
checked
{%
endif
%}
/>
<span
class=
"choice-text"
>
{{ choice.content|safe }}
</span>
</label>
<div
class=
"choice-tips"
></div>
<div
class=
"choice-tips-container"
>
<div
class=
"choice-tips"
></div>
</div>
</div>
{% endfor %}
<div
class=
"feedback"
></div>
...
...
mentoring/templates/html/ratingblock.html
View file @
dfb4cea9
...
...
@@ -4,40 +4,36 @@
<p>
{{ self.question }}
</p>
</legend>
<div
class=
"choices-list"
>
<div
class=
"choice"
>
<div
class=
"choice-result fa icon-2x"
></div>
<label><input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"1"
{%
if
self
.
student_choice =
=
'
1
'
%}
checked
{%
endif
%}
/>
1
</label>
<span
class=
"low"
>
- {{ self.low }}
</span>
<div
class=
"choice-tips"
></div>
</div>
<div
class=
"choice"
>
<div
class=
"choice-result fa icon-2x"
></div>
<label><input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"2"
{%
if
self
.
student_choice =
=
'
2
'
%}
checked
{%
endif
%}
/>
2
</label>
<div
class=
"choice-tips"
></div>
</div>
<div
class=
"choice"
>
<div
class=
"choice-result fa icon-2x"
></div>
<label><input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"3"
{%
if
self
.
student_choice =
=
'
3
'
%}
checked
{%
endif
%}
/>
3
</label>
<div
class=
"choice-tips"
></div>
</div>
<div
class=
"choice"
>
<div
class=
"choice-result fa icon-2x"
></div>
<label><input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"4"
{%
if
self
.
student_choice =
=
'
4
'
%}
checked
{%
endif
%}
/>
4
</label>
<div
class=
"choice-tips"
></div>
</div>
<div
class=
"choice"
>
<div
class=
"choice-result fa icon-2x"
></div>
<label><input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"5"
{%
if
self
.
student_choice =
=
'
5
'
%}
checked
{%
endif
%}
/>
5
</label>
<span
class=
"low"
>
- {{ self.high }}
</span>
<div
class=
"choice-tips"
></div>
</div>
{% for value in '12345' %}
<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=
"{{ value }}"
{%
if
self
.
student_choice =
=
value
%}
checked
{%
endif
%}
/>
{{ value }}
{% if forloop.first %}
<span
class=
"low"
>
- {{ self.low }}
</span>
{% endif %}
{% if forloop.last %}
<span
class=
"low"
>
- {{ self.high }}
</span>
{% endif %}
</label>
<div
class=
"choice-tips-container"
>
<div
class=
"choice-tips"
></div>
</div>
</div>
{% endfor %}
{% 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
%}
/>
<label
class=
"choice-label"
>
<input
class=
"choice-selector"
type=
"radio"
name=
"{{ self.name }}"
value=
"{{ choice.value }}"
{%
if
self
.
student_choice =
=
'{{
choice
.
value
}}'
%}
checked
{%
endif
%}
/>
<span
class=
"choice-text"
>
{{ choice.content|safe }}
</span>
</label>
<div
class=
"choice-tips"
></div>
<div
class=
"choice-tips-container"
>
<div
class=
"choice-tips"
></div>
</div>
</div>
{% endfor %}
<div
class=
"feedback"
></div>
...
...
mentoring/tests/integration/test_mcq.py
View file @
dfb4cea9
...
...
@@ -21,6 +21,9 @@
# Imports ###########################################################
import
ddt
from
mock
import
patch
,
Mock
from
mentoring
import
MentoringBlock
from
.base_test
import
MentoringBaseTest
...
...
@@ -76,11 +79,11 @@ class MCQBlockTest(MentoringBaseTest):
self
.
assertEqual
(
mcq1_choices
[
0
]
.
text
,
'Yes'
)
self
.
assertEqual
(
mcq1_choices
[
1
]
.
text
,
'Maybe not'
)
self
.
assertEqual
(
mcq1_choices
[
2
]
.
text
,
"I don't understand"
)
self
.
assertEqual
(
mcq2_choices
[
0
]
.
text
,
'1'
)
self
.
assertEqual
(
mcq2_choices
[
0
]
.
text
,
'1
- Not good at all
'
)
self
.
assertEqual
(
mcq2_choices
[
1
]
.
text
,
'2'
)
self
.
assertEqual
(
mcq2_choices
[
2
]
.
text
,
'3'
)
self
.
assertEqual
(
mcq2_choices
[
3
]
.
text
,
'4'
)
self
.
assertEqual
(
mcq2_choices
[
4
]
.
text
,
'5'
)
self
.
assertEqual
(
mcq2_choices
[
4
]
.
text
,
'5
- Extremely good
'
)
self
.
assertEqual
(
mcq2_choices
[
5
]
.
text
,
"I don't want to rate it"
)
mcq1_choices_input
=
self
.
_get_inputs
(
mcq1_choices
)
...
...
@@ -112,8 +115,13 @@ class MCQBlockTest(MentoringBaseTest):
submit
.
click
()
self
.
wait_until_disabled
(
submit
)
self
.
assertEqual
(
mcq1
.
find_element_by_css_selector
(
".feedback"
)
.
text
,
'Great!'
)
self
.
assertEqual
(
mcq2
.
find_element_by_css_selector
(
".feedback"
)
.
text
,
'Will do better next time...'
)
mcq1_tips
=
mcq1
.
find_element_by_css_selector
(
".choice-tips .tip p"
)
mcq2_tips
=
mcq2
.
find_element_by_css_selector
(
".choice-tips .tip p"
)
self
.
assertEqual
(
mcq1_tips
.
text
,
'Great!'
)
self
.
assertTrue
(
mcq1_tips
.
is_displayed
())
self
.
assertEqual
(
mcq2_tips
.
text
,
'Will do better next time...'
)
self
.
assertTrue
(
mcq2_tips
.
is_displayed
())
self
.
assertEqual
(
messages
.
text
,
''
)
self
.
assertFalse
(
messages
.
is_displayed
())
...
...
@@ -125,11 +133,32 @@ class MCQBlockTest(MentoringBaseTest):
submit
.
click
()
self
.
wait_until_disabled
(
submit
)
self
.
assertEqual
(
mcq1
.
find_element_by_css_selector
(
".feedback"
)
.
text
,
'Great!'
)
self
.
assertEqual
(
mcq2
.
find_element_by_css_selector
(
".feedback"
)
.
text
,
'I love good grades.'
)
mcq1_tips
=
mcq1
.
find_element_by_css_selector
(
".choice-tips .tip p"
)
mcq2_tips
=
mcq2
.
find_element_by_css_selector
(
".choice-tips .tip p"
)
self
.
assertEqual
(
mcq1_tips
.
text
,
'Great!'
)
self
.
assertTrue
(
mcq1_tips
.
is_displayed
())
self
.
assertEqual
(
mcq2_tips
.
text
,
'I love good grades.'
)
self
.
assertTrue
(
mcq2_tips
.
is_displayed
())
self
.
assertIn
(
'All is good now...
\n
Congratulations!'
,
messages
.
text
)
self
.
assertTrue
(
messages
.
is_displayed
())
# The choice tip containers should have the with-tips class.
mcq1_tip_containers
=
mcq1
.
find_elements_by_css_selector
(
'.choice-tips-container.with-tips'
)
mcq2_tip_containers
=
mcq2
.
find_elements_by_css_selector
(
'.choice-tips-container.with-tips'
)
self
.
assertEqual
(
len
(
mcq1_tip_containers
),
3
)
self
.
assertEqual
(
len
(
mcq2_tip_containers
),
6
)
# Clicking outside the tips should hide the tips and clear the with-tips class.
mcq1
.
find_element_by_css_selector
(
'.mentoring .question-title'
)
.
click
()
mcq2
.
find_element_by_css_selector
(
'.mentoring .question-title'
)
.
click
()
mcq1_tip_containers
=
mcq1
.
find_elements_by_css_selector
(
'.choice-tips-container.with-tips'
)
mcq2_tip_containers
=
mcq2
.
find_elements_by_css_selector
(
'.choice-tips-container.with-tips'
)
self
.
assertEqual
(
len
(
mcq1_tip_containers
),
0
)
self
.
assertEqual
(
len
(
mcq2_tip_containers
),
0
)
self
.
assertFalse
(
mcq1_tips
.
is_displayed
())
self
.
assertFalse
(
mcq2_tips
.
is_displayed
())
def
test_mcq_with_comments
(
self
):
mentoring
=
self
.
go_to_page
(
'Mcq With Comments 1'
)
mcq
=
mentoring
.
find_element_by_css_selector
(
'fieldset.choices'
)
...
...
@@ -231,3 +260,12 @@ class MCQBlockTest(MentoringBaseTest):
self
.
wait_until_disabled
(
submit
)
self
.
assertIn
(
'Congratulations!'
,
messages
.
text
)
@patch.object
(
MentoringBlock
,
'get_theme'
,
Mock
(
return_value
=
{
'package'
:
'mentoring'
,
'locations'
:
[
'public/themes/lms.css'
]}))
class
MCQBlockAprosThemeTest
(
MCQBlockTest
):
"""
Test MRQ/MCQ questions without the LMS theme which is on by default.
"""
pass
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