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