Commit e736ed34 by Arthur Barrett

added ability to hide/show instructions, if present

parent c3f55845
...@@ -93,6 +93,7 @@ class AnnotatableModule(XModule): ...@@ -93,6 +93,7 @@ class AnnotatableModule(XModule):
'display_name': self.display_name, 'display_name': self.display_name,
'element_id': self.element_id, 'element_id': self.element_id,
'discussion_id': self.discussion_id, 'discussion_id': self.discussion_id,
'instructions_html': self.instructions_html,
'content_html': self._render_content() 'content_html': self._render_content()
} }
...@@ -103,11 +104,25 @@ class AnnotatableModule(XModule): ...@@ -103,11 +104,25 @@ class AnnotatableModule(XModule):
XModule.__init__(self, system, location, definition, descriptor, XModule.__init__(self, system, location, definition, descriptor,
instance_state, shared_state, **kwargs) instance_state, shared_state, **kwargs)
self.element_id = self.location.html_id()
xmltree = etree.fromstring(self.definition['data']) xmltree = etree.fromstring(self.definition['data'])
# extract discussion id
self.discussion_id = xmltree.get('discussion', '') self.discussion_id = xmltree.get('discussion', '')
del xmltree.attrib['discussion'] del xmltree.attrib['discussion']
# extract instructions text (if any)
instructions = xmltree.find('instructions')
instructions_html = None
if instructions is not None:
instructions.tag = 'div'
instructions_html = etree.tostring(instructions, encoding='unicode')
xmltree.remove(instructions)
self.instructions_html = instructions_html
# everything else is annotatable content
self.content = etree.tostring(xmltree, encoding='unicode') self.content = etree.tostring(xmltree, encoding='unicode')
self.element_id = self.location.html_id()
class AnnotatableDescriptor(RawDescriptor): class AnnotatableDescriptor(RawDescriptor):
module_class = AnnotatableModule module_class = AnnotatableModule
......
.annotatable-header { .annotatable-header {
margin-bottom: 1em; margin-bottom: .5em;
.annotatable-title { .annotatable-title {
font-size: em(22); font-size: em(22);
text-transform: uppercase; text-transform: uppercase;
padding: 2px 4px; padding: 2px 4px;
} }
.annotatable-description { }
position: relative;
font-size: $body-font-size; .annotatable-description {
padding: 2px 4px; position: relative;
border: 1px solid $border-color; padding: 2px 4px;
border-radius: 3px; border: 1px solid $border-color;
.annotatable-toggle { border-radius: 3px;
position: absolute; margin-bottom: .5em;
right: 0; .annotatable-toggle {
margin: 2px 7px 2px 0; position: absolute;
} right: 0;
margin: 2px 7px 2px 0;
} }
} }
...@@ -50,62 +51,6 @@ ...@@ -50,62 +51,6 @@
} }
} }
.annotatable-problems {
margin: 25px 0 0 0;
.annotatable-discussion {
display: none;
}
.annotatable-problem {
border: 1px solid #ccc;
border-radius: 1em;
margin: 0 0 1em 0;
}
.annotatable-problem-header {
font-weight: bold;
border-bottom: 1px solid #ccc;
.annotatable-problem-index { font-weight: normal; }
}
.annotatable-problem-body {
position: relative;
textarea {
display: inline-block;
width: 55%;
}
.annotatable-problem-prompt {
font-style: italic;
}
ul.annotatable-problem-tags {
display: block;
list-style-type: none;
margin: 1em 0;
padding: 0;
li {
cursor: pointer;
display: inline;
padding: .5em;
margin: 0 .5em 0 0;
background-color: #ccc;
border: 1px solid #000;
&.selected {
background-color: rgba(255,255,10,0.3);
}
}
}
.annotatable-problem-controls {
display: inline-block;
margin: 0 4px 0 8px;
}
}
.annotatable-problem-footer {}
.annotatable-problem-header,
.annotatable-problem-body,
.annotatable-problem-footer {
padding: .5em 1em;
}
}
.ui-tooltip.qtip.ui-tooltip { .ui-tooltip.qtip.ui-tooltip {
font-size: $body-font-size; font-size: $body-font-size;
border: 1px solid #333; border: 1px solid #333;
......
class @Annotatable class @Annotatable
_debug: false _debug: false
wrapperSelector: '.annotatable-wrapper' wrapperSelector: '.annotatable-wrapper'
toggleSelector: '.annotatable-toggle' toggleAnnotationsSelector: '.annotatable-toggle-annotations'
spanSelector: '.annotatable-span' toggleInstructionsSelector: '.annotatable-toggle-instructions'
replySelector: '.annotatable-reply' instructionsSelector: '.annotatable-instructions'
spanSelector: '.annotatable-span'
problemXModuleSelector: '.xmodule_CapaModule' replySelector: '.annotatable-reply'
problemSelector: 'section.problem'
problemInputSelector: '.annotation-input' problemXModuleSelector: '.xmodule_CapaModule'
problemReturnSelector: 'section.problem .annotation-return' problemSelector: 'section.problem'
problemInputSelector: 'section.problem .annotation-input'
problemReturnSelector: 'section.problem .annotation-return'
constructor: (el) -> constructor: (el) ->
console.log 'loaded Annotatable' if @_debug console.log 'loaded Annotatable' if @_debug
...@@ -24,9 +26,12 @@ class @Annotatable ...@@ -24,9 +26,12 @@ class @Annotatable
@initTips() @initTips()
initEvents: () -> initEvents: () ->
# For handling hide/show of annotations # For handling hide/show of annotations and instructions
@annotationsHidden = false @annotationsHidden = false
@$(@toggleSelector).bind 'click', @onClickToggleAnnotations @$(@toggleAnnotationsSelector).bind 'click', @onClickToggleAnnotations
@instructionsHidden = false
@$(@toggleInstructionsSelector).bind 'click', @onClickToggleInstructions
# For handling 'reply to annotation' events that scroll to the associated capa problem. # For handling 'reply to annotation' events that scroll to the associated capa problem.
# These are contained in the tooltips, which should be rendered somewhere in the wrapper # These are contained in the tooltips, which should be rendered somewhere in the wrapper
...@@ -68,29 +73,15 @@ class @Annotatable ...@@ -68,29 +73,15 @@ class @Annotatable
events: events:
show: @onShowTip show: @onShowTip
onShowTip: (event, api) => onShowTip: (event, api) => event.preventDefault() if @annotationsHidden
event.preventDefault() if @annotationsHidden
onClickToggleAnnotations: (e) => @toggleAnnotations()
onClickToggleAnnotations: (e) =>
@toggleAnnotations() onClickToggleInstructions: (e) => @toggleInstructions()
onClickReply: (e) => onClickReply: (e) => @replyTo(e.currentTarget)
e.preventDefault()
offset = -20 onClickReturn: (e) => @returnFrom(e.currentTarget)
el = @getProblem e.currentTarget
if el.length > 0
@scrollTo(el, @afterScrollToProblem, offset)
else
console.log('problem not found. event: ', e) if @_debug
onClickReturn: (e) =>
e.preventDefault()
offset = -200
el = @getSpanForProblemReturn e.currentTarget
if el.length > 0
@scrollTo(el, @afterScrollToSpan, offset)
else
console.log('span not found. event:', e) if @_debug
getSpanForProblemReturn: (el) -> getSpanForProblemReturn: (el) ->
problem_id = $(@problemReturnSelector).index(el) problem_id = $(@problemReturnSelector).index(el)
...@@ -105,24 +96,48 @@ class @Annotatable ...@@ -105,24 +96,48 @@ class @Annotatable
toggleAnnotations: () -> toggleAnnotations: () ->
hide = (@annotationsHidden = not @annotationsHidden) hide = (@annotationsHidden = not @annotationsHidden)
@toggleButtonText hide @toggleAnnotationButtonText hide
@toggleSpans hide @toggleSpans hide
@toggleReturnLinks hide
@toggleTips hide @toggleTips hide
toggleTips: (hide) -> toggleTips: (hide) ->
if hide then @closeAndSaveTips() else @openSavedTips() if hide then @closeAndSaveTips() else @openSavedTips()
toggleReturnLinks: (hide) -> toggleAnnotationButtonText: (hide) ->
$(@returnSelector)[if hide then 'hide' else 'show']()
toggleButtonText: (hide) ->
buttonText = (if hide then 'Show' else 'Hide')+' Annotations' buttonText = (if hide then 'Show' else 'Hide')+' Annotations'
@$(@toggleSelector).text(buttonText) @$(@toggleAnnotationsSelector).text(buttonText)
toggleInstructions: () ->
hide = (@instructionsHidden = not @instructionsHidden)
@toggleInstructionsButtonText hide
@toggleInstructionsText hide
toggleInstructionsButtonText: (hide) ->
buttonText = (if hide then 'Show' else 'Hide')+' Instructions'
@$(@toggleInstructionsSelector).text(buttonText)
toggleInstructionsText: (hide) ->
@$(@instructionsSelector)[if hide then 'slideUp' else 'slideDown']()
toggleSpans: (hide) -> toggleSpans: (hide) ->
@$(@spanSelector).toggleClass 'hide', hide, 250 @$(@spanSelector).toggleClass 'hide', hide, 250
replyTo: (buttonEl) ->
offset = -20
el = @getProblem buttonEl
if el.length > 0
@scrollTo(el, @afterScrollToProblem, offset)
else
console.log('problem not found. event: ', e) if @_debug
returnFrom: (buttonEl) ->
offset = -200
el = @getSpanForProblemReturn buttonEl
if el.length > 0
@scrollTo(el, @afterScrollToSpan, offset)
else
console.log('span not found. event:', e) if @_debug
scrollTo: (el, after, offset = -20) -> scrollTo: (el, after, offset = -20) ->
$('html,body').scrollTo(el, { $('html,body').scrollTo(el, {
duration: 500 duration: 500
......
...@@ -23,18 +23,18 @@ ...@@ -23,18 +23,18 @@
}, },
onChangeComment: function(e) { onChangeComment: function(e) {
var value_el = this.findValueEl(e.target); var value_el = this.findValueEl(e.target);
var current_value = this.currentValue(value_el); var current_value = this.loadValue(value_el);
var target_value = $(e.target).val(); var target_value = $(e.target).val();
current_value.comment = target_value; current_value.comment = target_value;
this.setValue(value_el, current_value); this.storeValue(value_el, current_value);
}, },
onClickTag: function(e) { onClickTag: function(e) {
var target_el = e.target, target_value, target_index; var target_el = e.target, target_value, target_index;
var value_el, current_value; var value_el, current_value;
value_el = this.findValueEl(e.target); value_el = this.findValueEl(e.target);
current_value = this.currentValue(value_el); current_value = this.loadValue(value_el);
target_value = $(e.target).data('id'); target_value = $(e.target).data('id');
if(!$(target_el).hasClass('selected')) { if(!$(target_el).hasClass('selected')) {
...@@ -46,14 +46,14 @@ ...@@ -46,14 +46,14 @@
} }
} }
this.setValue(value_el, current_value); this.storeValue(value_el, current_value);
$(target_el).toggleClass('selected'); $(target_el).toggleClass('selected');
}, },
findValueEl: function(target_el) { findValueEl: function(target_el) {
var input_el = $(target_el).closest(this.inputSelector); var input_el = $(target_el).closest(this.inputSelector);
return $(this.valueSelector, input_el); return $(this.valueSelector, input_el);
}, },
currentValue: function(value_el) { loadValue: function(value_el) {
var json = $(value_el).val(); var json = $(value_el).val();
var result = JSON.parse(json); var result = JSON.parse(json);
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
return result; return result;
}, },
setValue: function(value_el, new_value) { storeValue: function(value_el, new_value) {
var json = JSON.stringify(new_value); var json = JSON.stringify(new_value);
$(value_el).val(json); $(value_el).val(json);
} }
......
...@@ -3,10 +3,19 @@ ...@@ -3,10 +3,19 @@
% if display_name is not UNDEFINED and display_name is not None: % if display_name is not UNDEFINED and display_name is not None:
<div class="annotatable-title">${display_name}</div> <div class="annotatable-title">${display_name}</div>
% endif % endif
<div class="annotatable-description"> </div>
Guided Discussion
<a class="annotatable-toggle" href="javascript:void(0)">Hide Annotations</a> % if instructions_html is not UNDEFINED and instructions_html is not None:
</div> <div class="annotatable-description">
</div> Instructions
<a class="annotatable-toggle annotatable-toggle-instructions" href="javascript:void(0)">Hide Instructions</a>
</div>
<div class="annotatable-instructions">${instructions_html}</div>
% endif
<div class="annotatable-description">
Guided Discussion
<a class="annotatable-toggle annotatable-toggle-annotations" href="javascript:void(0)">Hide Annotations</a>
</div>
<div class="annotatable-content">${content_html}</div> <div class="annotatable-content">${content_html}</div>
</div> </div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment