Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
RateXBlock
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
edx
RateXBlock
Commits
3a006d53
Commit
3a006d53
authored
Oct 06, 2015
by
Piotr Mitros
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Studio view
parent
73dc9e64
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
99 additions
and
18 deletions
+99
-18
rate/rate.py
+44
-10
rate/static/css/rate.css
+1
-1
rate/static/html/rate.html
+3
-3
rate/static/html/studio_view.html
+30
-0
rate/static/js/src/rate.js
+4
-4
rate/static/js/src/studio.js
+17
-0
No files found.
rate/rate.py
View file @
3a006d53
...
@@ -39,14 +39,17 @@ class RateXBlock(XBlock):
...
@@ -39,14 +39,17 @@ class RateXBlock(XBlock):
this.
this.
"""
"""
default_prompt
=
{
'
string
'
:
"Please provide us feedback on this section."
,
default_prompt
=
{
'
freeform
'
:
"Please provide us feedback on this section."
,
'likert'
:
"Please rate your overall experience with this section."
,
'likert'
:
"Please rate your overall experience with this section."
,
'mouseovers'
:[
"Excellent"
,
"Good"
,
"Average"
,
"Fair"
,
"Poor"
],
'mouseovers'
:[
"Excellent"
,
"Good"
,
"Average"
,
"Fair"
,
"Poor"
],
'icons'
:[
u"😁"
,
u"😊"
,
u"😐"
,
u"☹"
,
u"😟"
]}
'icons'
:[
u"😁"
,
u"😊"
,
u"😐"
,
u"☹"
,
u"😟"
]}
# This is a list of prompts. If we have multiple elements in the
# list, one will be chosen at random. This is currently not
# exposed in the UX. If the prompt is missing any portions, we
# will default to the ones in default_prompt.
prompts
=
List
(
prompts
=
List
(
default
=
[
default_prompt
,
default
=
[{
'freeform'
:
"What could be improved to make this section more clear?"
,
{
'string'
:
"What could be improved to make this section more clear?"
,
'likert'
:
"Was this section clear or confusing?."
}],
'likert'
:
"Was this section clear or confusing?."
}],
scope
=
Scope
.
settings
,
scope
=
Scope
.
settings
,
help
=
"Freeform user prompt"
,
help
=
"Freeform user prompt"
,
...
@@ -58,7 +61,6 @@ class RateXBlock(XBlock):
...
@@ -58,7 +61,6 @@ class RateXBlock(XBlock):
help
=
"Random number generated for p. -1 if uninitialized"
help
=
"Random number generated for p. -1 if uninitialized"
)
)
user_vote
=
Integer
(
user_vote
=
Integer
(
default
=-
1
,
scope
=
Scope
.
user_state
,
default
=-
1
,
scope
=
Scope
.
user_state
,
help
=
"How user voted. -1 if didn't vote"
help
=
"How user voted. -1 if didn't vote"
...
@@ -88,20 +90,29 @@ class RateXBlock(XBlock):
...
@@ -88,20 +90,29 @@ class RateXBlock(XBlock):
data
=
pkg_resources
.
resource_string
(
__name__
,
path
)
data
=
pkg_resources
.
resource_string
(
__name__
,
path
)
return
data
.
decode
(
"utf8"
)
return
data
.
decode
(
"utf8"
)
def
get_prompt
(
self
,
index
):
"""
Return the current prompt dictionary, doing appropriate
randomization if necessary, and falling back to defaults when
necessary.
"""
prompt
=
dict
(
self
.
default_prompt
)
prompt
.
update
(
self
.
prompts
[
index
])
return
prompt
def
student_view
(
self
,
context
=
None
):
def
student_view
(
self
,
context
=
None
):
"""
"""
The primary view of the RateXBlock, shown to students
The primary view of the RateXBlock, shown to students
when viewing courses.
when viewing courses.
"""
"""
if
self
.
prompt_choice
<
0
or
self
.
prompt_choice
>=
len
(
self
.
prompts
):
self
.
prompt_choice
=
random
.
randint
(
0
,
len
(
self
.
prompts
)
-
1
)
prompt
=
self
.
get_prompt
(
self
.
prompt_choice
)
# Figure out which prompt we show. We set self.prompt_choice to
# Figure out which prompt we show. We set self.prompt_choice to
# the index of the prompt. We set it if it is out of range (either
# the index of the prompt. We set it if it is out of range (either
# uninitiailized, or incorrect due to changing list length). Then,
# uninitiailized, or incorrect due to changing list length). Then,
# we grab the prompt, prepopulated with defaults.
# we grab the prompt, prepopulated with defaults.
if
self
.
prompt_choice
<
0
or
self
.
prompt_choice
>=
len
(
self
.
prompts
):
self
.
prompt_choice
=
random
.
randint
(
0
,
len
(
self
.
prompts
)
-
1
)
prompt
=
dict
(
self
.
default_prompt
)
prompt
.
update
(
self
.
prompts
[
self
.
prompt_choice
])
# Now, we render the RateXBlock. This may be redundant, since we
# Now, we render the RateXBlock. This may be redundant, since we
# don't always show it.
# don't always show it.
...
@@ -110,7 +121,7 @@ class RateXBlock(XBlock):
...
@@ -110,7 +121,7 @@ class RateXBlock(XBlock):
indexes
=
range
(
len
(
prompt
[
'icons'
]))
indexes
=
range
(
len
(
prompt
[
'icons'
]))
active_vote
=
[
"checked"
if
i
==
self
.
user_vote
else
""
for
i
in
indexes
]
active_vote
=
[
"checked"
if
i
==
self
.
user_vote
else
""
for
i
in
indexes
]
scale
=
u""
.
join
(
scale_item
.
format
(
level
=
level
,
icon
=
icon
,
i
=
i
,
active
=
active
)
for
(
level
,
icon
,
i
,
active
)
in
zip
(
prompt
[
'mouseovers'
],
prompt
[
'icons'
],
indexes
,
active_vote
))
scale
=
u""
.
join
(
scale_item
.
format
(
level
=
level
,
icon
=
icon
,
i
=
i
,
active
=
active
)
for
(
level
,
icon
,
i
,
active
)
in
zip
(
prompt
[
'mouseovers'
],
prompt
[
'icons'
],
indexes
,
active_vote
))
rendered
=
html
.
format
(
self
=
self
,
scale
=
scale
,
string_prompt
=
prompt
[
'string
'
],
likert_prompt
=
prompt
[
'likert'
])
rendered
=
html
.
format
(
self
=
self
,
scale
=
scale
,
freeform_prompt
=
prompt
[
'freeform
'
],
likert_prompt
=
prompt
[
'likert'
])
# We initialize self.p_r if not initialized -- this sets whether
# We initialize self.p_r if not initialized -- this sets whether
# or not we show it. From there, if it is less than odds of showing,
# or not we show it. From there, if it is less than odds of showing,
...
@@ -131,6 +142,29 @@ class RateXBlock(XBlock):
...
@@ -131,6 +142,29 @@ class RateXBlock(XBlock):
frag
.
initialize_js
(
'RateXBlock'
)
frag
.
initialize_js
(
'RateXBlock'
)
return
frag
return
frag
def
studio_view
(
self
,
context
):
"""
Create a fragment used to display the edit view in the Studio.
"""
html_str
=
pkg_resources
.
resource_string
(
__name__
,
"static/html/studio_view.html"
)
prompt
=
self
.
get_prompt
(
0
)
frag
=
Fragment
(
unicode
(
html_str
)
.
format
(
**
prompt
))
js_str
=
pkg_resources
.
resource_string
(
__name__
,
"static/js/src/studio.js"
)
frag
.
add_javascript
(
unicode
(
js_str
))
frag
.
initialize_js
(
'RateBlock'
)
return
frag
@XBlock.json_handler
def
studio_submit
(
self
,
data
,
suffix
=
''
):
"""
Called when submitting the form in Studio.
"""
print
data
self
.
prompts
[
0
][
'freeform'
]
=
data
.
get
(
'freeform'
)
self
.
prompts
[
0
][
'likert'
]
=
data
.
get
(
'likert'
)
return
{
'result'
:
'success'
}
@XBlock.json_handler
@XBlock.json_handler
def
vote
(
self
,
data
,
suffix
=
''
):
def
vote
(
self
,
data
,
suffix
=
''
):
"""
"""
...
@@ -155,7 +189,7 @@ class RateXBlock(XBlock):
...
@@ -155,7 +189,7 @@ class RateXBlock(XBlock):
@XBlock.json_handler
@XBlock.json_handler
def
feedback
(
self
,
data
,
suffix
=
''
):
def
feedback
(
self
,
data
,
suffix
=
''
):
tracker
.
emit
(
'edx.ratexblock.
string
_feedback'
,
tracker
.
emit
(
'edx.ratexblock.
freeform
_feedback'
,
{
'old_feedback'
:
self
.
user_feedback
,
{
'old_feedback'
:
self
.
user_feedback
,
'new_feedback'
:
data
[
'feedback'
]})
'new_feedback'
:
data
[
'feedback'
]})
self
.
user_feedback
=
data
[
'feedback'
]
self
.
user_feedback
=
data
[
'feedback'
]
...
...
rate/static/css/rate.css
View file @
3a006d53
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
border-radius
:
5px
;
border-radius
:
5px
;
}
}
.rate_block
.rate_
string
_input
{
.rate_block
.rate_
freeform
_input
{
margin-bottom
:
1em
;
margin-bottom
:
1em
;
}
}
...
...
rate/static/html/rate.html
View file @
3a006d53
<div
class=
"rate_block"
>
<div
class=
"rate_block"
>
<div
class=
"rate_header"
>
{
string
_prompt}
</div>
<div
class=
"rate_header"
>
{
freeform
_prompt}
</div>
<div
class=
"rate_
string
_input"
>
<div
class=
"rate_
freeform
_input"
>
<textarea
class=
"rate_
string
_area"
rows=
"4"
cols=
"30"
>
{self.user_feedback}
</textarea>
<textarea
class=
"rate_
freeform
_area"
rows=
"4"
cols=
"30"
>
{self.user_feedback}
</textarea>
<div
class=
"rate_thank_you"
>
Thank you!
</div>
<div
class=
"rate_thank_you"
>
Thank you!
</div>
</div>
</div>
<div
class=
"rate_likert_header"
>
{likert_prompt}
</div>
<div
class=
"rate_likert_header"
>
{likert_prompt}
</div>
...
...
rate/static/html/studio_view.html
0 → 100644
View file @
3a006d53
<div
class=
"wrapper-comp-settings is-active editor-with-buttons"
id=
"settings-tab"
>
<ul
class=
"list-input settings-list"
>
<li
class=
"field comp-setting-entry is-set"
>
<div
class=
"wrapper-comp-setting"
>
<label
class=
"label setting-label"
for=
"freeform"
>
Freeform prompt
</label>
<input
class=
"input setting-input"
name=
"freeform"
id=
"freeform"
value=
"{freeform}"
type=
"text"
/>
</div>
<span
class=
"tip setting-help"
>
Example: Please provide us feedback on this section.
</span>
</li>
<li
class=
"field comp-setting-entry is-set"
>
<div
class=
"wrapper-comp-setting"
>
<label
class=
"label setting-label"
for=
"likert"
>
Likert prompt
</label>
<input
class=
"input setting-input"
name=
"likert"
id=
"likert"
value=
"{likert}"
type=
"text"
/>
</div>
<span
class=
"tip setting-help"
>
Example: Please rate your overall experience with this section.
</span>
</li>
<div
class=
"xblock-actions"
>
<ul>
<li
class=
"action-item"
>
<a
href=
"#"
class=
"button action-primary save-button"
>
Save
</a>
</li>
<li
class=
"action-item"
>
<a
href=
"#"
class=
"button cancel-button"
>
Cancel
</a>
</li>
</ul>
</div>
</div>
rate/static/js/src/rate.js
View file @
3a006d53
...
@@ -27,14 +27,14 @@ function RateXBlock(runtime, element) {
...
@@ -27,14 +27,14 @@ function RateXBlock(runtime, element) {
Logger
.
log
(
"edx.ratexblock.likert_rate"
,
{
"vote"
:
vote
})
Logger
.
log
(
"edx.ratexblock.likert_rate"
,
{
"vote"
:
vote
})
});
});
$
(
'.rate_
string
_area'
,
element
).
change
(
function
(
eventObject
)
{
$
(
'.rate_
freeform
_area'
,
element
).
change
(
function
(
eventObject
)
{
$
(
'.rate_thank_you'
,
element
).
css
(
'visibility'
,
'hidden'
);
$
(
'.rate_thank_you'
,
element
).
css
(
'visibility'
,
'hidden'
);
var
feedback_
string
=
eventObject
.
currentTarget
.
value
;
var
feedback_
freeform
=
eventObject
.
currentTarget
.
value
;
Logger
.
log
(
"edx.ratexblock.
string_feedback"
,
{
"feedback"
:
feedback_string
})
Logger
.
log
(
"edx.ratexblock.
freeform_feedback"
,
{
"feedback"
:
feedback_freeform
})
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
feedback_handler
,
url
:
feedback_handler
,
data
:
JSON
.
stringify
({
"feedback"
:
feedback_
string
}),
data
:
JSON
.
stringify
({
"feedback"
:
feedback_
freeform
}),
success
:
function
()
{
$
(
'.rate_thank_you'
,
element
).
css
(
'visibility'
,
'visible'
)},
success
:
function
()
{
$
(
'.rate_thank_you'
,
element
).
css
(
'visibility'
,
'visible'
)},
});
});
});
});
...
...
rate/static/js/src/studio.js
0 → 100644
View file @
3a006d53
function
RateBlock
(
runtime
,
element
)
{
$
(
element
).
find
(
'.save-button'
).
bind
(
'click'
,
function
()
{
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'studio_submit'
);
var
data
=
{
likert
:
$
(
element
).
find
(
'input[name=likert]'
).
val
(),
freeform
:
$
(
element
).
find
(
'input[name=freeform]'
).
val
()
};
runtime
.
notify
(
'save'
,
{
state
:
'start'
});
$
.
post
(
handlerUrl
,
JSON
.
stringify
(
data
)).
done
(
function
(
response
)
{
runtime
.
notify
(
'save'
,
{
state
:
'end'
});
});
});
$
(
element
).
find
(
'.cancel-button'
).
bind
(
'click'
,
function
()
{
runtime
.
notify
(
'cancel'
,
{});
});
}
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