Commit 0b266098 by Prem Sichanugrist

Rewrite Sequence module to use unobtrusive JS

parent f467134f
......@@ -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>')
return {'content':content,
"destroy_js":m['destroy_js'],
'init_js':m['init_js'],
content=json.dumps(m['content'])
content=content.replace('</script>', '<"+"/script>')
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)
......
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"
<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>
// 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 } );
});
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