Microsoft's 3 jQuery plugins have been accepted as official plugins (with templating being absorbed into the core in jQuery 1.5). Lets have a quick look at what they provide.
There are a ton of blog posts and documentation out there describing what these plugins do,
I am going to ignore Globalisation for now as it takes too long to put a worthwhile demo together and it's alreaqdy heavily explained on the GitHub page linked above. So lets take the other plugins and use them to create "the best todo app evar"
ToDo App
Lets take a simple to do app the you can add Tasks to (along with associated comments) then save them to the server. Simple design like so,
[[posterous-content:iesdxxncdohkDnbunIad]]
HTML
So first things first lets get the HTML out of the way,
<h1>ToDo List</h1>
<form id="new-task-form" action="\">
<p>
<label for="task">Task:</label>
<input type="text" id="task" name="task"/>
</p>
<p>
<label for="note">Note:</label>
<textarea id="note" name="note" rows="5" cols="30"></textarea>
</p>
<input type="button" value="Add" id="add"/>
<input type="button" value="Save" id="save"/>
</form>
<h2>Current ToDos</h2>
<ul id="todo-list"></ul>
JavaScript
Next up is the interesting part - JavaScript,
var model = {}, // empty model object
list = $("#todo-list"),
form = $('#new-task-form'),
addBtn = $("#add"),
saveBtn = $("#save");
// link ui to model
form.link(model);
// handle onclick
addBtn.click(function () {
// clone the data model
var item = $.extend({}, model)
// generate template
$.tmpl("<li>${task}</li>", item).appendTo(list);
});
// handle save
saveBtn.click(function () {
// pull back the data
var todos = list.find("li").map(function () {
return $(this).tmplItem().data;
}).get();
// save the object
$.post("/Home/Save", todos, function () {
alert("Todos Saved");
});
});
That's it. So lets break it down and see exactly what is happening.
Variable Declarations
var model = {}, // empty model object
First thing we do is declare a model object. Simply an empty object for our purposes but could be pre-populated with data that can be bound.
Model Linking
Model linking is effectively 2 way data binding between a data context and a form (1 way optional and configurable mappings possible see API).
// link ui to model
form.link(model);
We just want simple 2 way binding so that is all we need. This sets up the 2 form inputs so they are bound to our model object so any changes will be reflected accordingly.
Add Functionality
// clone the data model
var item = $.extend({}, model)
$.tmpl("<li>${task}</li>", item).appendTo(list);
First things first we need to take a clone of the current object as this is bound/linked to the form and if we don't clone it we will be referencing the same object over and over. This wont affect the UI but templating has some nice data centric features to pull back our data later and we need this.
Next we create a very simple template passing the cloned model into the template call. Finally we append this new LI to the UL list.
Save Functionality
The interesting part of the save functionality is how we actually pull back the list of data to be sent to the server.
// pull back the data
var todos = list.find("li").map(function () {
return $(this).tmplItem().data;
}).get();
Templates are data centric. That is, when they are created the original data that was used to generate them is stored in the jQuery data cache and can be retrieved using tmplItem. So rather than having to scrape the data back from UI (where are you going to get the comment value from?) you can simply ask for the elements data context.
So...
That's it. Some very nice data centric (3rd time in as many paragraphs) plugins. Sure you can do this stuff without these plugins but it would certainly not be as elegant. This is only skimming the surface of the data linking and templating plugins, there is a heap of stuff that I didn't cover,
- One way binding
- Value converters for binding
- Programatically change data values
- Adding custom linking behaviour
- Generate templats from embedded script templates
- Complex and nested templating
- Statically define a reusable template