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