Commit 6e93b42f authored by S Anand's avatar S Anand

BUG: enable $.template selector: option. Interactive docs

parent 98c5a54f
Pipeline #76845 passed with stage
in 2 minutes and 16 seconds
This is the contents of the file "template.html".
It is rendered as a template. 1 + 2 = <%- 1 + 2 %>.
......@@ -20,14 +20,15 @@ This displays `Your platform is ...` and shows the userAgent just below the scri
The template can use all global variables. You can pass additional variables
using as `.template({var1: value, var2: value, ...})`. For example:
<!-- render:html -->
```html
<script type="text/html">
<script type="text/html" class="example">
<% list.forEach(function(item) { %>
<div><%= item %></div>
<% }) %>
</script>
<script>
$('body').template({list: ['a', 'b', 'c']})
$('script.example').template({list: ['a', 'b', 'c']})
</script>
```
......@@ -45,21 +46,22 @@ for this to work.
For example, this shows a circle in SVG bouncing around smoothly.
<!-- render:html -->
```html
<style>
circle { transition: all 1s ease; }
</style>
<script src="../node_modules/morphdom/dist/morphdom-umd.min.js"></script>
<script type="text/html">
<svg width="100" height="100">
<script src="../../ui/morphdom/dist/morphdom-umd.min.js"></script>
<script type="text/html" data-engine="vdom" class="bouncing-ball">
<svg width="500" height="50">
<circle cx="<%= x %>" cy="<%= y %>" r="5" fill="red"/>
</svg>
</script>
<script>
setInterval(function() {
var x = Math.random() * 100
var y = Math.random() * 100
$('body').template({x: x, y: y}) // Update the template to animate
var x = Math.random() * 500
var y = Math.random() * 50
$('.bouncing-ball').template({x: x, y: y}) // Update the template to animate
}, 1000)
</script>
```
......@@ -77,42 +79,60 @@ To re-use the template or render the same template on a different DOM node,
run `.template(data, {target: selector})`. This allows you to declare templates
once and apply them across the body. For example:
```js
$('script.chart')
.template({heading: 'Dashboard 1'}, {target: '.dashboard1'})
.template({heading: 'Dashboard 2'}, {target: '.dashboard2'})
.template({}, {target: '.no-heading'})
<!-- render:html -->
```html
<div class="panel1 bg-primary text-white px-3"></div>
<div class="panel2 bg-success text-white px-3"></div>
<script type="text/html" class="targeted">
The same template is rendered in <%- heading %>
</script>
<script>
$('script.targeted')
.template({heading: 'panel 1'}, {target: '.panel1'})
.template({heading: 'panel 2'}, {target: '.panel2'})
</script>
```
The target can also be specified via a `data-target=".dashboard1"` on the script
template. This is the same as specifying `{target: '.dashboard'}`. For example:
The target can also be specified via a `data-target=".panel1"` on the script
template. This is the same as specifying `{target: '.panel'}`. For example:
```html
<script class="chart" data-target=".dashboard1">...</script>
<script class="chart" data-target=".dashboard2">...</script>
<script class="chart" data-target=".panel1">...</script>
<script class="chart" data-target=".panel2">...</script>
```
## $.template append
To append instead of replacing, run `.template(data, {append: true})`. Every
time `.template` is called, it appends rather than replaces. For example:
To append instead of replacing, use `data-append="true"`. Every time `.template`
is called, it appends rather than replaces. For example:
```js
<!-- render:html -->
```html
<script type="text/html" class="list" data-append="true">
<li>New item #<%- n %> appended</li>
</script>
<script>
$('script.list')
.template({heading: 'Item 1'}, {append: true}), // Appends the heading
.template({heading: 'Item 2'}, {append: true}), // instead of replacing it
.template({n: 1})
.template({n: 2})
</script>
```
You can also specify this as `<script data-append="true">`. This helps append to
an existing target. For example:
You can also specify this as `.template(data, {append: true})`. You can also
append to an [existing target](#template-targets). For example:
<!-- render:html -->
```html
<script class="list" data-append="true" data-target=".existing-list">...</script>
<ul class="existing list">
<ul class="existing-list">
<li>Existing item</li>
<!-- Every time .template() is called, the result is added as a list item here -->
</ul>
<script>
$('script.list')
.template({n: 1}, {append: true, target: '.existing-list'})
.template({n: 2}, {append: true, target: '.existing-list'})
</script>
```
......@@ -120,10 +140,11 @@ an existing target. For example:
Template containers can have an `src=` attribute that loads the template from a file:
<!-- render:html -->
```html
<script type="text/html" src="template.html"></script>
<script type="text/html" src="template.html" class="source"></script>
<script>
$('body').template()
$('script.source').template()
</script>
```
......@@ -135,36 +156,43 @@ as a template. The template can use:
For example:
<!-- render:html -->
```html
<script type="text/html" src="missing.html">
Template returned error code: <%= xhr.status %>.
<script type="text/html" src="missing.html" class="missing">
Template returned HTTP error code: <%= xhr.status %>.
Data is <%= data %>
</script>
<script>
$('body').template({data: data})
$('script.missing').template({data: [1, 2, 3]})
</script>
```
## $.template selector
`$().template()` renders all `script[type="text/html"]` nodes in or under the
`$(...).template()` renders all `script[type="text/html"]` nodes in or under the
selected node. Use `data-selector=` attribute to change the selector. For
example:
<!-- render:html -->
```html
<section data-selector="script.lodash-template">
<script class="lodash-template">...</script>
<section data-selector=".render">
<script type="text/html" class="no-render">This will not render</script>
<script type="text/html" class="render">This will render</script>
</section>
<script>
$('section').template()
$('section[data-selector]').template()
</script>
```
You can also render a template by selecting it directly. For example:
You can also use the `selector: ...` option. For example:
<!-- render:html -->
```html
<div class="selector-target"></div>
<script type="text/html" class="try no-render">This will not render</script>
<script type="text/html" class="try render">This will render</script>
<script>
$('script.lodash-template').template()
$('script.try').template({}, {selector: '.render', target: '.selector-target'})
</script>
```
......@@ -177,12 +205,17 @@ You can also render a template by selecting it directly. For example:
For example:
```js
$('script[type="text/html"]')
.on('template', function(e) { // Returns nodes rendered by the template
e.target // Get the target nodes
.filter('div') // Filter all <div> elements inside
.attr('class', 'item') // Change their class
<!-- render:html -->
```html
<script type="text/html" class="event">
<pre>Event e.templatedata = <span class="data">filled by event handler</span></pre>
</script>
<script>
$('script.event')
.on('template', function(e) { // When the template is rendered,
$(e.target).find('.data') // find the <pre> tag inside target nodes
.html(JSON.stringify(e.templatedata)) // and enter the template data
})
.template() // Trigger the template AFTER binding the event handler
.template({x: 1}) // Trigger template AFTER .on('template')
</script>
```
import { findall } from './_util.js'
export function template(data, options) {
var selector = this.data('selector') || 'script[type="text/html"]'
options = options || {}
var selector = options.selector || this.data('selector') || 'script[type="text/html"]'
// Pre-create the template rendering function
// Store this in .data('template.function')
......@@ -17,7 +18,8 @@ export function template(data, options) {
$.get(src)
.done(function (html) { make_template($this, html, data, options) })
.fail(function (xhr) {
make_template($this, $this.html(), _.extend({ xhr: xhr }, data, options))
data.xhr = xhr
make_template($this, $this.html(), data, options)
})
} else
// If no src= is specified, just render the contents
......@@ -42,8 +44,6 @@ var _prev_target = 'template.prev_target'
function make_template($this, html, data, default_options) {
var compiled_template = _.template(html)
var $target
if (!default_options)
default_options = {}
function renderer(data, options) {
html = compiled_template(data)
// Get options. DOM data-* over-rides JS options
......
......@@ -5,7 +5,7 @@
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../node_modules/lodash/lodash.min.js"></script>
<script src="../node_modules/morphdom/dist/morphdom-umd.min.js"></script>
<script src="../dist/template.min.js"></script>
<script src="../dist/g1.js"></script>
<script src="tape.js"></script>
<script src="tape-stream.js"></script>
<style>
......@@ -130,8 +130,8 @@
</script>
<section id="root2" data-selector="script.template">
<script type="text/html"><div class="result"><%= 1 + 1 %></div></script>
<script type="text/html" class="template"><div class="result"><%= 2 + 2 %></div></script>
<script type="text/html"><div class="result"><%= 1 + 1 %></div></script>
</section>
<script>
tape('$().template() accepts data-selector to select sub-elements', function (t) {
......@@ -143,6 +143,20 @@
})
</script>
<section id="root3">
<script type="text/html" class="template"><div class="result"><%= 2 + 2 %></div></script>
<script type="text/html"><div class="result"><%= 1 + 1 %></div></script>
</section>
<script>
tape('$().template() accepts selector: to select sub-elements', function (t) {
// The second template (with .template) is triggered, not the first one
$('#root3').on('template', function (e) {
t.equal(e.target.filter('.result').text(), '4')
t.end()
}).template({}, {selector: '.template'})
})
</script>
<script class="target-dom" data-target=".target1" type="text/html">1 + 1 = <%= 1 + 1 %></script>
<script class="target-dom" type="text/html">2 + 2 = <%= 2 + 2 %></script>
<div class="target1"></div>
......
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