We have a new adapter module that supports closer integration with the Handlebar template engine. With this you can have your online or offline data converted to HTML in a matter of seconds. Beyond simple HTML rendering the Handlebars module provides some basic but very effective support for commanding: handling user interface events in the scope of data.
The Handlebars module works both with the JayData Entity Classes and also with the JayData ItemStore APIs.
Before we begin…
1 2 3 4 5 |
<span class="kwrd"><</span><span class="html">script</span> <span class="attr">type</span><span class="kwrd">="text/javascript"</span> <span class="attr">src</span><span class="kwrd">="http://code.jquery.com/jquery.js"</span><span class="kwrd">></</span><span class="html">script</span><span class="kwrd">></span> <script type=<span class="str">"text/javascript"</span> src=<span class="str">"http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.rc.1/handlebars.js"</span>></script> <script type=<span class="str">"text/javascript"</span> src=<span class="str">"http://include.jaydata.org/jaydata.js"</span>></script> <script type=<span class="str">"text/javascript"</span> src=<span class="str">"http://include.jaydata.org/jaydatamodules/handlebars.js"</span>><span class="kwrd"></</span><span class="html">script</span><span class="kwrd">></span> |
These are the necessary files you’ll need for the below examples to work. All major HTML5 compatible desktop and mobile browsers are supported, plus Internet Explorer 9. By default data defined and stored in the example code are put into the best local data storage your browser offers. See this in more details on where your data is actually stored.
Display a solo data item
item.render
Data objects – entities – defined and created with JayData now have a render method inherited from the $data.Entity base class. Without parameters the render method uses the default template for the given data type. The type’s default template is the one with an id value that matches the type’s name.
1 2 3 4 5 6 7 8 9 |
<span class="kwrd"><</span><span class="html">script</span><span class="kwrd">></span> <span class="kwrd">var</span> Todo = $data.define(<span class="str">"<span style="color: #000000; font-size: medium;"><strong>Todo</strong></span>"</span>, { Task: String, Completed: Boolean, DueDate: Date }); $(<span class="kwrd">function</span> () { <span class="kwrd">var</span> todo = <span class="kwrd">new</span> Todo({Task: <span class="str">"Do something"</span> }); $(<span class="str">'#todoList'</span>).append( |
todo.render
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
()); }); <span class="kwrd"></</span><span class="html">script</span><span class="kwrd">></span> <span class="kwrd"></</span><span class="html">head</span><span class="kwrd">></span> <span class="kwrd"><</span><span class="html">body</span><span class="kwrd">></span> <span class="kwrd"><</span><span class="html">script</span> <span class="attr">id</span><span class="kwrd">="<span style="color: #000000; font-size: medium;"><strong>Todo</strong></span>"</span> <span class="attr">type</span><span class="kwrd">="text/x-handlebars-template"</span><span class="kwrd">></span> <li>{{Task}}</li> <span class="kwrd"></</span><span class="html">script</span><span class="kwrd">></span> <span class="kwrd"><</span><span class="html">ul</span> <span class="attr">id</span><span class="kwrd">="todoList"</span><span class="kwrd">></span> <span class="kwrd"></</span><span class="html">ul</span><span class="kwrd">></span> <span class="kwrd"></</span><span class="html">body</span><span class="kwrd">></span> <span class="kwrd"></</span><span class="html">html</span><span class="kwrd">></span> |
Defining types with $data.define the function results the same JayData classes as when using the $data.Entity.extend method.
Render with template markup
You can specify templates inline, by calling the render method with the template markup. The following example saves a new Todo item to the default item store (without any configuration this is the browser’s local data storage) then displays the new item in a list. Notice that the Id field is automatically populated by the data storage.
CODE:
1 2 3 4 |
$data(<span class="str">"Todo"</span>) .save({ Task: <span class="str">"New task"</span> }) .then(<span class="kwrd">function</span> (todo) { $(<span class="str">'#todoList'</span>).append( |
todo.render
1 2 |
(<span class="str">"<li>{{Task}},{{Id}}</li>"</span>)); }); |
result:
Named templates
Code:
1 2 3 4 5 |
$data(<span class="str">"Todo"</span>) .read(1) .then(<span class="kwrd">function</span> (todo) { $(<span class="str">'#todoList'</span>).append(<strong><span style="font-size: medium;">todo.render</span></strong>(<span class="str">"<strong><span style="color: #000000; font-size: medium;">TodoTemplate</span></strong>"</span>)); }); |
Markup:
1 2 3 4 5 6 7 8 |
<body> <script id=<span class="str">"<strong><span style="font-size: medium;">TodoTemplate</span></strong>"</span> type=<span class="str">"text/x-handlebars"</span>> <li>{{Task}}</li> </script> <ul id=<span class="str">"todoList"</span>> </ul> </body> |
item.renderTo
Spare some extra lines with the renderTo method. The renderTo function executes the render method then appends the result to the selected node.
1 2 3 4 5 6 7 |
$data(<span class="str">"Todo"</span>) .read(1) .then(<span class="kwrd">function</span> (todo) { <strong><span style="font-size: medium;">todo.renderTo</span></strong>(<span class="str">"#todoList"</span>, <span class="str">"TodoTemplate"</span>); }); }); |
The renderTo method has 3 parameters: selector, template and renderMode. The renderMode parameter defaults to “replaceContent” with “replace”, “append”,”after”,”before” being the other options.
This example uses the Entity Classes API to list all Todo items.
1 2 3 4 |
db.Items .filter(<span class="str">"it.Completed == null || it.Completed != true"</span>) .forEach(<span class="kwrd">function</span> (todo) { |
todo.renderTo
1 2 3 |
(<span class="str">"#todoList"</span>,<span class="str">"<li>{{Task}}</li>"</span>,<span class="str">"append"</span>); }); |
type.render
Sometimes the data in your hand is just raw json). This case you can use the static render method on the type.
1 |
$(<span class="str">"<ul></ul>"</span>).append(<strong><span style="font-size: medium;">$data(<span class="str">"Todo"</span>).render</span></strong>({Task:<span class="str">"Hello"</span>})) |
1 |
$(<span class="str">"<ul></ul>"</span>).append(<strong><span style="font-size: medium;">$data(<span class="str">"Todo"</span>).render</span></strong>({Task:<span class="str">"Hello"</span>},<span class="str">"<li>{{Task}}</li>"</span>)) |
$data.renderTo
This one is an interesting beast. The renderTo static method on the $data global is provided for a more convenient fluent coding experience. Its return value is actually a function that plays nicely with the promise oriented fluent api.
1 2 3 4 |
$data(<span class="str">"Todo"</span>) .save({ Task: <span class="str">"Step 2: build your code"</span> }) .then(<strong><span style="font-size: medium;">$data.renderTo</span></strong>(<span class="str">"#todoList"</span>)) .then(/* continue with something */); |
The above code is equivalent with this:
$data(“Todo”) .save({ Task: “Step 2: build your code” }) .then(function (todo) { todo.renderTo(“#todoList”); return todo; }).then(/* continue with something */);
With the Entity Classes API:
1 2 3 4 |
db.Items .single(<span class="str">"it.Id == 1"</span>) .then(<strong><span style="font-size: medium;">$data.renderTo</span></strong>(<span class="str">"#todoList"</span>)); |
Displaying a list of data items
type.renderItems
1 2 3 4 5 6 7 8 |
$data(<span class="str">"Todo"</span>) .readAll() .then(<span class="kwrd">function</span> (todos) { <span class="kwrd">var</span> html = <strong><span style="font-size: medium;">$data(<span class="str">"Todo"</span>).renderItems</span></strong>(todos, “<li>{{Task}}</li>”); $(<span class="str">'#todoList'</span>).append(html); </code><code class="language-javascript"> <span class="kwrd">return</span> todos; </code><code class="language-javascript"> }); |
$data.renderItemsTo
Similar to $data.renderTo, the $data.renderItemsTo deals with the individual items and provides for cleaner code altogether. The above example is equivalent with this:
1 2 3 4 |
$data(<span class="str">"Todo"</span>) .query("it.Completed != true”) .then(<strong><span style="font-size: medium;">$data.renderItemsTo</span></strong>(<span class="str">"#todoList"</span>,<span class="str">"<li>{{Task}}</li>"</span>)); </code><code class="language-javascript"> .then(…) |
The same syntax work with the Entity Classes API too. This example falls back to the Todo default template.
1 2 3 4 5 |
db.TodoItems .filter(<span class="str">"it.Completed == true"</span>) .toArray() .then(<strong><span style="font-size: medium;">$data.renderItemsTo</span></strong>(<span class="str">"#todoList"</span>)) </code><code class="language-javascript"> .then(…) |
$data.renderTo
To deal with the result collection and not with individual items use the $data.renderTo method with a template that is executed around an array of items:
1 2 3 4 |
$data(<span class="str">"Todo"</span>) .readAll() .then($data.renderTo(<span class="str">"#todoList"</span>, <span class="str">"TodoArrayTemplate"</span>)); }); |
Markup:
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="kwrd"><</span><span class="html">script</span> <span class="attr">id</span><span class="kwrd">="TodoArrayTemplate"</span> <span class="attr">type</span><span class="kwrd">="text/x-handlebars"</span><span class="kwrd">></span> <div>Total items: {{length}}</div> <ul> {{#each .}} <li>{{Task}}</li> {{/each}} </ul> <span class="kwrd"></</span><span class="html">script</span><span class="kwrd">></span> <span class="kwrd"><</span><span class="html">div</span> <span class="attr">id</span><span class="kwrd">="todoList"</span><span class="kwrd">></span> <span class="kwrd"></</span><span class="html">div</span><span class="kwrd">></span> |
Queryable.renderItemsTo
This is solely for the Entit Classes API (as the ItemStore hides the actual Queryable instance from you). The above code can be written like this:
1 2 3 4 |
db.TodoItems .filter(<span class="str">"it.Completed == true"</span>) .<strong><span style="font-size: medium;">renderItemsTo</span></strong>(<span class="str">"#todoList"</span>, <span class="str">"<li>{{Task}}</li>"</span>) .then(<span class="rem">/*do something with the items*/</span>); |
Queryable.renderTo
1 2 3 4 |
db.TodoItems .filter(<span class="str">"it.Completed == true"</span>) <strong><span style="font-size: medium;">.renderTo</span></strong>(<span class="str">"#todoList"</span>, <span class="str">"{{#each .}}{{Task}}{{/each}}"</span>) .then(<span class="rem">/*do something with the items*/</span>); |
If you found this article useful read more on Handlebars helpers and commanding to see how to develop a master-detail scenario with four lines of code.