Commit c2ad71f8 by Filippo Valsorda

Move the templates out of .js and use Handlebars

parent 5f390be4
......@@ -12,7 +12,7 @@ from xblock.core import XBlock
from xblock.fields import Scope, String, Dict, Float
from xblock.fragment import Fragment
from .utils import render_template
from .utils import render_template, load_resource
# Globals ###########################################################
......@@ -77,8 +77,10 @@ class DragAndDropBlock(XBlock):
max_score_string = '({0} Point{1} Possible)'.format(int(self.weight),
's' if self.weight > 1 else '') if self.weight else ''
js_templates = load_resource('/templates/html/js_templates.html')
context = {
'js_templates': js_templates,
'title': self.display_name,
'question_text': self.question_text,
'max_score_string': max_score_string
......@@ -93,7 +95,7 @@ class DragAndDropBlock(XBlock):
fragment.add_javascript_url(self.runtime.local_resource_url(self,
'public/js/vendor/jquery.html5-placeholder-shim.js'))
fragment.add_javascript_url(self.runtime.local_resource_url(self,
'public/js/vendor/underscore1.6.0.js'))
'public/js/vendor/handlebars-v1.1.2.js'))
fragment.add_javascript_url(self.runtime.local_resource_url(self,
'public/js/drag_and_drop.js'))
......@@ -106,7 +108,10 @@ class DragAndDropBlock(XBlock):
Editing view in Studio
"""
context = {}
js_templates = load_resource('/templates/html/js_templates.html')
context = {
'js_templates': js_templates,
}
fragment = Fragment()
fragment.add_content(render_template('/templates/html/drag_and_drop_edit.html', context))
......@@ -117,7 +122,7 @@ class DragAndDropBlock(XBlock):
fragment.add_javascript_url(self.runtime.local_resource_url(self,
'public/js/vendor/jquery.html5-placeholder-shim.js'))
fragment.add_javascript_url(self.runtime.local_resource_url(self,
'public/js/vendor/underscore1.6.0.js'))
'public/js/vendor/handlebars-v1.1.2.js'))
fragment.add_javascript_url(self.runtime.local_resource_url(self,
'public/js/drag_and_drop_edit.js'))
......
......@@ -24,40 +24,22 @@ function DragAndDropBlock(runtime, element) {
}
},
// item template
tpl: {
item: function() {
return [
'<li class="option" data-value="<%= id %>"',
'style="width: <%= size.width %>; height: <%= size.height %>">',
'<%= displayName %>',
'</li>'
].join('');
},
image_item: function() {
return [
'<li class="option" data-value="<%= id %>"',
'style="width: <%= size.width %>; height: <%= size.height %>">',
'<img src="<%= backgroundImage %>" />',
'</li>'
].join('');
},
zoneElement: function() {
return [
'<div id="<%= id %>" class="zone" data-zone="<%= title %>" style="',
'top:<%= y %>px;',
'left:<%= x %>px;',
'width:<%= width %>px;',
'height:<%= height %>px;">',
'<p><%= title %></p>',
'</div>'
].join('');
init: function() {
_fn.tpl = {
item: Handlebars.compile($("#item-tpl", element).html()),
imageItem: Handlebars.compile($("#image-item-tpl", element).html()),
zoneElement: Handlebars.compile($("#zone-element-tpl", element).html())
};
}
},
init: function(data) {
_fn.data = data;
// Compile templates
_fn.tpl.init();
// Add the items to the page
_fn.items.draw();
_fn.zones.draw();
......@@ -183,14 +165,14 @@ function DragAndDropBlock(runtime, element) {
draw: function() {
var list = [],
items = _fn.data.items,
tpl = _fn.tpl.item(),
img_tpl = _fn.tpl.image_item();
tpl = _fn.tpl.item,
img_tpl = _fn.tpl.imageItem;
items.forEach(function(item) {
if (item.backgroundImage.length > 0) {
list.push(_.template(img_tpl, item));
list.push(img_tpl(item));
} else {
list.push(_.template(tpl, item));
list.push(tpl(item));
}
});
......@@ -206,12 +188,12 @@ function DragAndDropBlock(runtime, element) {
draw: function() {
var html = [],
zones = _fn.data.zones,
tpl = _fn.tpl.zoneElement(),
tpl = _fn.tpl.zoneElement,
i,
len = zones.length;
for (i=0; i<len; i++) {
html.push(_.template(tpl, zones[i]));
html.push(tpl(zones[i]));
}
// Update DOM
......
......@@ -5,74 +5,14 @@ function DragAndDropEditBlock(runtime, element) {
// DOM Elements
$target: $('.xblock--drag-and-drop .target-img', element),
// item template
tpl: {
zoneInput: function() {
return [
'<div class="zone-row <%= name %>">',
'<label>Text</label>',
'<input type="text" class="title" placeholder="<%= title %>" />',
'<a href="#" class="remove-zone hidden">',
'<div class="icon remove"></div>',
'</a>',
'<div class="layout">',
'<label>width</label>',
'<input type="text" class="size width" value="200" />',
'<label>height</label>',
'<input type="text" class="size height" value="100" />',
'<br />',
'<label>x</label>',
'<input type="text" class="coord x" value="0" />',
'<label>y</label>',
'<input type="text" class="coord y" value="0" />',
'</div>',
'</div>'
].join('');
},
zoneElement: function() {
return [
'<div id="<%= id %>" class="zone" data-zone="<%= title %>" style="',
'top:<%= y %>px;',
'left:<%= x %>px;',
'width:<%= width %>px;',
'height:<%= height %>px;">',
'<p><%= title %></p>',
'</div>'
].join('');
},
zoneDropdown: '<option value="<%= value %>"><%= value %></option>',
itemInput: function() {
return [
'<div class="item">',
'<div class="row">',
'<label>Text</label>',
'<input type="text" class="item-text"></input>',
'<label>Zone</label>',
'<select class="zone-select"><%= dropdown %></select>',
'<a href="#" class="remove-item hidden">',
'<div class="icon remove"></div>',
'</a>',
'</div>',
'<div class="row">',
'<label>Background image URL (alternative to the text)</label>',
'<textarea class="background-image"></textarea>',
'</div>',
'<div class="row">',
'<label>Success Feedback</label>',
'<textarea class="success-feedback"></textarea>',
'</div>',
'<div class="row">',
'<label>Error Feedback</label>',
'<textarea class="error-feedback"></textarea>',
'</div>',
'<div class="row">',
'<label>Width (px - 0 for auto)</label>',
'<input type="text" class="item-width" value="190"></input>',
'<label>Height (px - 0 for auto)</label>',
'<input type="text" class="item-height" value="0"></input>',
'</div>',
'</div>'
].join('');
init: function() {
_fn.tpl = {
zoneInput: Handlebars.compile($("#zone-input-tpl", element).html()),
zoneElement: Handlebars.compile($("#zone-element-tpl", element).html()),
zoneDropdown: Handlebars.compile($("#zone-dropdown-tpl", element).html()),
itemInput: Handlebars.compile($("#item-input-tpl", element).html()),
};
}
},
......@@ -95,6 +35,9 @@ function DragAndDropEditBlock(runtime, element) {
init: function(data) {
_fn.data = data;
// Compile templates
_fn.tpl.init();
_fn.build.clickHandlers();
_fn.build.form.zone.add();
},
......@@ -165,8 +108,8 @@ function DragAndDropEditBlock(runtime, element) {
}
},
add: function(e) {
var inputTemplate = _fn.tpl.zoneInput(),
zoneTemplate = _fn.tpl.zoneElement(),
var inputTemplate = _fn.tpl.zoneInput,
zoneTemplate = _fn.tpl.zoneElement,
name = 'zone-',
$elements = _fn.build.$el,
num,
......@@ -196,14 +139,14 @@ function DragAndDropEditBlock(runtime, element) {
_fn.build.form.zone.obj.push(zoneObj);
// Add fields to zone position form
$elements.zones.form.append(_.template(inputTemplate, {
$elements.zones.form.append(inputTemplate({
title: 'Zone ' + num,
name: name
}));
_fn.build.form.zone.enableDelete();
// Add zone div to target
$elements.target.append(_.template(zoneTemplate, zoneObj));
$elements.target.append(zoneTemplate(zoneObj));
// Listen to changes in form to update zone div
_fn.build.form.zone.clickHandler(num);
......@@ -314,14 +257,14 @@ function DragAndDropEditBlock(runtime, element) {
html;
for (i=0; i<len; i++) {
dropdown.push(_.template(tpl, { value: arr[i] }));
dropdown.push(tpl({ value: arr[i] }));
}
// Add option to include dummy answers
dropdown.push(_.template(tpl, { value: 'none' }));
dropdown.push(tpl({ value: 'none' }));
html = dropdown.join('');
_fn.build.form.zone.dropdown = html;
_fn.build.form.zone.dropdown = new Handlebars.SafeString(html);
_fn.build.$el.items.form.find('.zone-select').html(html);
},
feedback: function($form) {
......@@ -334,14 +277,14 @@ function DragAndDropEditBlock(runtime, element) {
count: 0,
add: function(e) {
var $form = _fn.build.$el.items.form,
tpl = _fn.tpl.itemInput();
tpl = _fn.tpl.itemInput;
if (e) {
e.preventDefault();
}
_fn.build.form.item.count++;
$form.append(_.template(tpl, { dropdown: _fn.build.form.zone.dropdown }));
$form.append(tpl({ dropdown: _fn.build.form.zone.dropdown }));
_fn.build.form.item.enableDelete();
// Placeholder shim for IE9
......
<section class="xblock--drag-and-drop">
{{ js_templates|safe }}
<h2 class="problem-header">
{{ title }}
</h2>
......
{% load i18n %}
<div class="xblock--drag-and-drop editor-with-buttons">
{{ js_templates|safe }}
<section class="drag-builder">
<div class="tab feedback-tab">
......
<script id="item-tpl" type="text/html">
<li class="option" data-value="{{ id }}"
style="width: {{ size.width }}; height: {{ size.height }}">
{{ displayName }}
</li>
</script>
<script id="image-item-tpl" type="text/html">
<li class="option" data-value="{{ id }}"
style="width: {{ size.width }}; height: {{ size.height }}">
<img src="{{ backgroundImage }}" />
</li>
</script>
<script id="zone-element-tpl" type="text/html">
<div id="{{ id }}" class="zone" data-zone="{{ title }}" style="
top:{{ y }}px;
left:{{ x }}px;
width:{{ width }}px;
height:{{ height }}px;">
<p>{{ title }}</p>
</div>
</script>
<script id="zone-input-tpl" type="text/html">
<div class="zone-row {{ name }}">
<label>Text</label>
<input type="text" class="title" placeholder="{{ title }}" />
<a href="#" class="remove-zone hidden">
<div class="icon remove"></div>
</a>
<div class="layout">
<label>width</label>
<input type="text" class="size width" value="200" />
<label>height</label>
<input type="text" class="size height" value="100" />
<br />
<label>x</label>
<input type="text" class="coord x" value="0" />
<label>y</label>
<input type="text" class="coord y" value="0" />
</div>
</div>
</script>
<script id="zone-dropdown-tpl" type="text/html">
<option value="{{ value }}">{{ value }}</option>
</script>
<script id="item-input-tpl" type="text/html">
<div class="item">
<div class="row">
<label>Text</label>
<input type="text" class="item-text"></input>
<label>Zone</label>
<select class="zone-select">{{ dropdown }}</select>
<a href="#" class="remove-item hidden">
<div class="icon remove"></div>
</a>
</div>
<div class="row">
<label>Background image URL (alternative to the text)</label>
<textarea class="background-image"></textarea>
</div>
<div class="row">
<label>Success Feedback</label>
<textarea class="success-feedback"></textarea>
</div>
<div class="row">
<label>Error Feedback</label>
<textarea class="error-feedback"></textarea>
</div>
<div class="row">
<label>Width (px - 0 for auto)</label>
<input type="text" class="item-width" value="190"></input>
<label>Height (px - 0 for auto)</label>
<input type="text" class="item-height" value="0"></input>
</div>
</div>
</script>
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