Rewrite Sequence module to use unobtrusive JS
This commit is contained in:
@@ -28,14 +28,6 @@ class Module(XModule):
|
||||
self.render()
|
||||
return self.content
|
||||
|
||||
def get_init_js(self):
|
||||
self.render()
|
||||
return self.init_js
|
||||
|
||||
def get_destroy_js(self):
|
||||
self.render()
|
||||
return self.destroy_js
|
||||
|
||||
def handle_ajax(self, dispatch, get):
|
||||
if dispatch=='goto_position':
|
||||
self.position = int(get['position'])
|
||||
@@ -45,45 +37,40 @@ class Module(XModule):
|
||||
def render(self):
|
||||
if self.rendered:
|
||||
return
|
||||
def j(m):
|
||||
def j(m):
|
||||
''' jsonify contents so it can be embedded in a js array
|
||||
We also need to split </script> tags so they don't break
|
||||
mid-string'''
|
||||
if 'init_js' not in m: m['init_js']=""
|
||||
if 'type' not in m: m['init_js']=""
|
||||
content=json.dumps(m['content'])
|
||||
content=content.replace('</script>', '<"+"/script>')
|
||||
content=json.dumps(m['content'])
|
||||
content=content.replace('</script>', '<"+"/script>')
|
||||
|
||||
return {'content':content,
|
||||
"destroy_js":m['destroy_js'],
|
||||
'init_js':m['init_js'],
|
||||
return {'content':content,
|
||||
'type': m['type']}
|
||||
|
||||
|
||||
## Returns a set of all types of all sub-children
|
||||
child_classes = [set([i.tag for i in e.iter()]) for e in self.xmltree]
|
||||
|
||||
self.titles = json.dumps(["\n".join([i.get("name").strip() for i in e.iter() if i.get("name") != None]) \
|
||||
for e in self.xmltree])
|
||||
titles = ["\n".join([i.get("name").strip() for i in e.iter() if i.get("name") != None]) \
|
||||
for e in self.xmltree]
|
||||
|
||||
self.contents = [j(self.render_function(e)) \
|
||||
for e in self.xmltree]
|
||||
|
||||
print self.titles
|
||||
for i in range(len(self.contents)):
|
||||
self.contents[i]['title'] = titles[i]
|
||||
|
||||
for (content, element_class) in zip(self.contents, child_classes):
|
||||
new_class = 'other'
|
||||
for c in class_priority:
|
||||
if c in element_class:
|
||||
if c in element_class:
|
||||
new_class = c
|
||||
content['type'] = new_class
|
||||
|
||||
js=""
|
||||
|
||||
params={'items':self.contents,
|
||||
'id':self.item_id,
|
||||
'position': self.position,
|
||||
'titles':self.titles,
|
||||
'titles':titles,
|
||||
'tag':self.xmltree.tag}
|
||||
|
||||
# TODO/BUG: Destroy JavaScript should only be called for the active view
|
||||
@@ -94,16 +81,11 @@ class Module(XModule):
|
||||
destroy_js="".join([e['destroy_js'] for e in self.contents if 'destroy_js' in e])
|
||||
|
||||
if self.xmltree.tag in ['sequential', 'videosequence']:
|
||||
self.init_js=js+render_to_string('seq_module.js',params)
|
||||
self.destroy_js=destroy_js
|
||||
self.content=render_to_string('seq_module.html',params)
|
||||
if self.xmltree.tag == 'tab':
|
||||
params['id'] = 'tab'
|
||||
self.init_js=js+render_to_string('tab_module.js',params)
|
||||
self.destroy_js=destroy_js
|
||||
self.content=render_to_string('tab_module.html',params)
|
||||
self.rendered = True
|
||||
|
||||
|
||||
def __init__(self, system, xml, item_id, state=None):
|
||||
XModule.__init__(self, system, xml, item_id, state)
|
||||
|
||||
70
templates/coffee/src/modules/sequence.coffee
Normal file
70
templates/coffee/src/modules/sequence.coffee
Normal file
@@ -0,0 +1,70 @@
|
||||
class window.Sequence
|
||||
constructor: (@id, @elements, @tag, position) ->
|
||||
@buildNavigation()
|
||||
@bind()
|
||||
@render position
|
||||
|
||||
bind: ->
|
||||
$('#sequence-list a').click @goto
|
||||
|
||||
buildNavigation: ->
|
||||
$.each @elements, (index, item) ->
|
||||
link = $('<a>').attr class: "seq_#{item.type}_inactive", 'data-element': index + 1
|
||||
title = $('<p>').html(item.title)
|
||||
list_item = $('<li>').append(link.append(title))
|
||||
$('#sequence-list').append list_item
|
||||
|
||||
toggleArrows: ->
|
||||
$('.sequence-nav-buttons a').unbind('click')
|
||||
|
||||
if @position == 1
|
||||
$('.sequence-nav-buttons .prev a').addClass('disabled')
|
||||
else
|
||||
$('.sequence-nav-buttons .prev a').removeClass('disabled').click(@previous)
|
||||
|
||||
if @position == @elements.length
|
||||
$('.sequence-nav-buttons .next a').addClass('disabled')
|
||||
else
|
||||
$('.sequence-nav-buttons .next a').removeClass('disabled').click(@next)
|
||||
|
||||
render: (new_position) ->
|
||||
if @position != undefined
|
||||
@mark_visited @position
|
||||
$.post "/modx/#{@tag}/#{@id}/goto_position", position: new_position
|
||||
|
||||
if @position != new_position
|
||||
@mark_active new_position
|
||||
$('#seq_content').html eval(@elements[new_position - 1].content)
|
||||
|
||||
MathJax.Hub.Queue(["Typeset",MathJax.Hub])
|
||||
@position = new_position
|
||||
@toggleArrows()
|
||||
|
||||
goto: (e) =>
|
||||
e.preventDefault()
|
||||
new_position = $(e.srcElement).data('element')
|
||||
log_event("seq_goto", old: @position, new: new_position, id: @id)
|
||||
@render new_position
|
||||
|
||||
next: (e) =>
|
||||
e.preventDefault()
|
||||
new_position = @position + 1
|
||||
log_event("seq_next", old: @position, new: new_position, id: @id)
|
||||
@render new_position
|
||||
|
||||
previous: (e) =>
|
||||
e.preventDefault()
|
||||
new_position = @position - 1
|
||||
log_event("seq_prev", old: @position, new: new_position, id: @id)
|
||||
@render new_position
|
||||
|
||||
link_for: (position) ->
|
||||
$("#sequence-list a[data-element=#{position}]")
|
||||
|
||||
mark_visited: (position) ->
|
||||
@link_for(position).attr class: "seq_#{@elements[position - 1].type}_visited"
|
||||
|
||||
mark_active: (position) ->
|
||||
@link_for(position).attr class: "seq_#{@elements[position - 1].type}_active"
|
||||
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
<nav aria-label="Section Navigation" class="sequence-nav">
|
||||
<ol>
|
||||
% for t in range(1,1+len(items)):
|
||||
<li><a href="#" class="seq_inactive" id="tt_${ t }"></a></li>
|
||||
% endfor
|
||||
</ol>
|
||||
<div id="sequence_${id}" class="sequence">
|
||||
<nav aria-label="Section Navigation" class="sequence-nav">
|
||||
<ol id="sequence-list">
|
||||
</ol>
|
||||
|
||||
<ul>
|
||||
<li class="${ id }prev prev"><a href="#">Previous</a></li>
|
||||
<li class="${ id }next next"><a href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<ul class="sequence-nav-buttons">
|
||||
<li class="prev"><a href="#">Previous</a></li>
|
||||
<li class="next"><a href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div id="seq_content"></div>
|
||||
<div id="seq_content"></div>
|
||||
|
||||
<nav class="sequence-bottom">
|
||||
<ul aria-label="Section Navigation">
|
||||
<li class="${ id }prev prev"><a href="#">Previous</a></li>
|
||||
<li class="${ id }next next"><a href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="sequence-bottom">
|
||||
<ul aria-label="Section Navigation" class="sequence-nav-buttons">
|
||||
<li class="prev"><a href="#">Previous</a></li>
|
||||
<li class="next"><a href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<%block name="js_extra">
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
new Sequence('${id}', ${items}, '${tag}', ${position});
|
||||
});
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
// IMPORTANT TODO: Namespace
|
||||
|
||||
var ${ id }contents=["",
|
||||
%for t in items:
|
||||
${t['content']} ,
|
||||
%endfor
|
||||
""
|
||||
];
|
||||
|
||||
var ${ id }types=["",
|
||||
%for t in items:
|
||||
"${t['type']}" ,
|
||||
%endfor
|
||||
""
|
||||
];
|
||||
|
||||
var ${ id }init_functions=["",
|
||||
%for t in items:
|
||||
function(){ ${t['init_js']} },
|
||||
%endfor
|
||||
""];
|
||||
|
||||
var ${ id }titles=${titles};
|
||||
|
||||
var ${ id }destroy_functions=["",
|
||||
%for t in items:
|
||||
function(){ ${t['destroy_js']} },
|
||||
%endfor
|
||||
""];
|
||||
|
||||
var ${ id }loc = -1;
|
||||
function disablePrev() {
|
||||
var i=${ id }loc-1;
|
||||
log_event("seq_prev", {'old':${id}loc, 'new':i,'id':'${id}'});
|
||||
if (i < 1 ) {
|
||||
$('.${ id }prev a').addClass('disabled');
|
||||
} else {
|
||||
$('.${ id }prev a').removeClass('disabled');
|
||||
};
|
||||
}
|
||||
|
||||
function disableNext() {
|
||||
var i=${ id }loc+1;
|
||||
log_event("seq_next", {'old':${id}loc, 'new':i,'id':'${id}'});
|
||||
|
||||
if(i > ${ len(items) } ) {
|
||||
$('.${ id }next a').addClass('disabled');
|
||||
} else {
|
||||
$('.${ id }next a').removeClass('disabled');
|
||||
};
|
||||
}
|
||||
|
||||
function ${ id }goto(i) {
|
||||
log_event("seq_goto", {'old':${id}loc, 'new':i,'id':'${id}'});
|
||||
|
||||
postJSON('${ MITX_ROOT_URL }/modx/${tag}/${ id }/goto_position',
|
||||
{'position' : i });
|
||||
|
||||
if (${ id }loc!=-1)
|
||||
${ id }destroy_functions[ ${ id }loc ]();
|
||||
$('#seq_content').html(${ id }contents[i]);
|
||||
${ id }init_functions[i]()
|
||||
//$('#tt_'+${ id }loc).attr("style", "background-color:gray");
|
||||
$('#tt_'+${ id }loc).removeClass();
|
||||
$('#tt_'+${ id }loc).addClass("seq_"+${ id }types[${ id }loc]+"_visited");
|
||||
${ id }loc=i;
|
||||
//$('#tt_'+i).attr("style", "background-color:red");
|
||||
$('#tt_'+i).removeClass();
|
||||
$('#tt_'+i).addClass("seq_"+${ id }types[${ id }loc]+"_active");
|
||||
|
||||
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
|
||||
|
||||
disableNext();
|
||||
disablePrev();
|
||||
}
|
||||
|
||||
function ${ id }setup_click(i) {
|
||||
$('#tt_'+i).click(function(eo) { ${ id }goto(i);});
|
||||
$('#tt_'+i).addClass("seq_"+${ id }types[i]+"_inactive");
|
||||
$('#tt_'+i).append("<p>" + ${ id }titles[i-1] + "</p>");
|
||||
|
||||
}
|
||||
|
||||
function ${ id }next() {
|
||||
var i=${ id }loc+1;
|
||||
log_event("seq_next", {'old':${id}loc, 'new':i,'id':'${id}'});
|
||||
if(i > ${ len(items) } ) {
|
||||
i = ${ len(items) };
|
||||
} else {
|
||||
${ id }goto(i);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function ${ id }prev() {
|
||||
var i=${ id }loc-1;
|
||||
log_event("seq_prev", {'old':${id}loc, 'new':i,'id':'${id}'});
|
||||
if (i < 1 ) {
|
||||
i = 1;
|
||||
} else {
|
||||
${ id }goto(i);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(function() {
|
||||
var i;
|
||||
for(i=1; i<${ len(items)+1 }; i++) {
|
||||
${ id }setup_click(i);
|
||||
}
|
||||
|
||||
|
||||
$('.${ id }next a').click(function(eo) { ${ id }next(); return false;});
|
||||
$('.${ id }prev a').click(function(eo) { ${ id }prev(); return false;});
|
||||
${ id }goto( ${ position } );
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user