Commit 99318a5d authored by S Anand's avatar S Anand
Browse files

ENH: $.template() accepts a target to render at

parent 1c14350a
Pipeline #38203 passed with stage
in 1 minute and 19 seconds
......@@ -130,7 +130,16 @@ using as `.template({var1: value, var2: value, ...})`. For example:
</script>
```
To re-render the template, run `.template()` again with different data.
To re-render the template, run `.template(data)` again with different data.
To re-use the template, i.e. render the same template on a different DOM node, run `.template(data, target)`. This allows you to declare templates once and apply them across the body. For example:
```js
$('script.chart')
.template({heading: 'Dashboard 1'}, '.dashboard1')
.template({heading: 'Dashboard 2'}, '.dashboard2')
.template({}, '.no-heading')
```
## $.template attributes
......
......@@ -10,18 +10,26 @@ var _renderer = 'template.render',
// - stores the target node in $this.data('template.target')
// - triggers a template event (with .templatedata, .target)
// - returns the target node
function make_template($this, html, data) {
function make_template($this, html, data, default_target) {
var template = _.template(html)
function renderer(data) {
// Clear old target nodes if any
var $target = $this.data(_target)
if ($target)
$target.remove()
var $target
function renderer(data, target) {
// Parse the template output and create a node collection
// $.parseHTML ensures that "hello" is parsed as HTML, not a selector
$target = $($.parseHTML(template(data))).insertAfter($this)
// Store the target node for future reference
$this.data(_target, $target)
$target = $($.parseHTML(template(data)))
if (typeof target == 'undefined')
target = default_target
if (typeof target == 'undefined') {
// Clear old target nodes if any
var $old_target = $this.data(_target)
if ($old_target)
$old_target.remove()
// Store the target nodes for future reference
$this.after($target)
.data(_target, $target)
} else {
$(target).html($target)
}
// Trigger the template event
$this.trigger({type: 'template', templatedata: data, target: $target})
return $target
......@@ -30,7 +38,7 @@ function make_template($this, html, data) {
return renderer(data)
}
export function template(data) {
export function template(data, target) {
var selector = this.data('selector') || 'script[type="text/html"]'
// Pre-create the template rendering function
......@@ -45,16 +53,16 @@ export function template(data) {
// If the AJAX load succeeds, render the loaded template
// Else render the contents, with an additional xhr variable
$.get(src)
.done(function(html) { make_template($this, html, data) })
.done(function(html) { make_template($this, html, data, target) })
.fail(function(xhr) {
make_template($this, $this.html(), _.extend({xhr: xhr}, data))
make_template($this, $this.html(), _.extend({xhr: xhr}, data, target))
})
} else
// If no src= is specified, just render the contents
make_template($this, $this.html(), data)
make_template($this, $this.html(), data, target)
} else
// If the renderer is already present, just use it
renderer(data)
renderer(data, target)
})
return this
}
......@@ -14,9 +14,12 @@
<script type="text/html" id="t1">Your platform is <%= navigator.userAgent %></script>
<script>
function strip(text) {
return text.replace(/^\s+/, '').replace(/\s+$/, '')
}
function text(target) {
var node = target.get(0)
return node ? node.textContent.replace(/^\s+/, '').replace(/\s+$/, '') : ''
return node ? strip(node.textContent) : ''
}
tape('$().template() renders plain text with variables', function(t) {
t.plan(2)
......@@ -81,6 +84,28 @@
})
</script>
<script type="text/html" id="t5">
<%= heading %>
</script>
<div class="dashboard1">has <em>old content</em></div>
<div class="dashboard2">has <em>old content</em></div>
<script>
tape('$().template(data, target) renders template to any DOM element', function(t) {
$('#t5')
.one('template', function(e) {
t.equal(text(e.target), 'Dashboard 1', 'renders with data')
t.equal(strip($('.dashboard1').html()), 'Dashboard 1', 'renders to target')
})
.template({ heading: 'Dashboard 1' }, '.dashboard1')
.one('template', function (e) {
t.equal(text(e.target), 'Dashboard 2')
t.equal(strip($('.dashboard2').html()), 'Dashboard 2', 'renders to target')
t.end()
})
.template({ heading: 'Dashboard 2' }, '.dashboard2')
})
</script>
<section class="root1">
<script type="text/html"><%= 1 + 1 %></script>
<script type="text/html"><%= 2 + 2 %></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