The jQuery Fuzzytoast plugin aims to easily combine data from standard REST calls with "templates" and insert the results back into the HTML layout.

This goal removes xSP processing from the server to the client, making the server work significantly more straight-forward and easier. However, to help with the added complexity of the client, we've created this project.

Usage

The easiest way to use this plugin is to place a fuzzytoast aspect on a button or some other object and have it grab an online template, some data from a REST call and insert it as the child of some element, as in:

$('#some-buttom').fuzzytoast ({ 
    template: 'templates/about.html',
    data    : 'rest/some-data.json' 
});

This call makes many assumptions, but the fuzzytoast parameters are the following:

You can also set up defaults for all requests. These defaults include:

Utility Functions

Templates themselves may contain data that needs to call the fuzzytoast system, and in this case, you can build up the dynamic aspects by first creating the action, and then calling it, as in:

var id = $.fuzzytoast.create({
    template    : 'templates/profile.html',
    data        : 'data/user/'+$(this).attr('id')+'.json',
    destination : '#main'
});															
$.fuzzytoast(id);

Or doing this with a single call to $.fuzzytoast() as in:

$.fuzzytoast({
    template    : 'templates/profile.html',
    data        : 'data/user/'+$(this).attr('id')+'.json',
    destination : '#main'
});

A couple of reasons why you would want to use the utility function form of $.fuzzytoast() instead of the initial selector method usage described above, e.g. $('#selector').fuzzytoast():

First, the $(this) is not available without being inside a function call.

Second, you might want to kick off the call with something other than a click, as in:

$('#user-list li').
    hover(
        function() {
            $(this).addClass('ui-state-hover'); 			
            $.fuzzytoast({
                    template    : 'templates/profile.html', 
                    data        : 'data/user/'+$(this).attr('id')+'.json', 
                    destination : '#main'					
                });
        },
        function() { $(this).removeClass('ui-state-hover'); }	
    );

Multiple Data Sources

The data parameter can either be a string containing the URL to access for the data, or an object containing multiple sources. For example:

$.fuzzytoast({
    template    : 'templates/dashboard.html',
    data        : {
                     'apps'    : '/apps/v1/details',
                     'services': '/srvs/v1/details',
                     'profile' : '/profile/' + id
                  },
    destination : '#main'
});

In this example, the plugin will retrieve the JSON document from each of the three URLs, and make them available to the template. Each JSON object can then be referenced by the key given in the data. For example:

{
  'apps'    : [ { 'id':42, 'name':'mongrue' }, 
                { 'id':34, 'name':'fuzzytoes' }
              ],
  'services': [ { 'id':3, 'name':'mongodb-1.8', 'type':'mongodb' },
                { 'id':4, 'name':'redis-cep', 'type':'redis' } 
              ],
  'profile' : { 'name': 'Mickey Mouse', 
                'email': 'gloves@disney.com'
              }
}

If you are using Mustache, your template could access that data in this way:

Note: If any of the data sources fail, then error() callback function is called, and the success() function will not... Even if two of the three succeed.

Template Features

While FuzzyToast needs a template engine, it doesn't supply one. You use whatever system you want, by simply including a system. For example:

<script type="text/javascript" src="js/libs/mustache.js"></script>

If it is one of the ones listed below, FuzzyToast will recognize it, and use it:

Whatever template engine you use, we've added a feature to allow partial templates, where a template can include the contents of another template. For instance, if you were using jQuery Templates, and foo.html contains:

<h1>Hello, ${user.name}</h1>
<div>
{{INCLUDE bar.html}}
</div>

And bar.html contains:

Books read:
<ul>
  {{each(book) user.books}}
    <li> ${book.name} </li>
  {{/each}}
</ul>

The template that is processed with the model would look like this:

<h1>Hello, ${user.name}</h1>
<div>
Books read:
<ul>
  {{each(book) user.books}}
    <li> ${book.name} </li>
  {{/each}}
</ul>
</div>

Included templates can include other templates. Oh yeah, the {{INCLUDE ...}} must be in uppercase. Didn't want to risk conflicts with the template engine.

Using Other Template Systems

We have chosen to support a few popular template engines, but you can use others... (see this presentation) you just have to tell us how to call it, by setting the following variables:

If you have a template system that doesn't behave in one of the ways listed above, you can easily create your own render() function, and do the processing yourself. If Handlebars wasn't so damn cool, we probably would have only supported that approach.

Handling Errors

Of course, you get errors... especially when dealing with a lot of downloaded files and web services. We've attempted to make this part simple.

You can either add a error function reference to a link, or you can specify the function reference for all links by setting the $.fuzzytoast.default_error value.

Assuming we have the following modal dialog template embedded in our page (instead of attempting to download it at run-time from our server):

<script type="text/x-jquery-tmpl" id="errorTemplate">
    The request we made to the web service returned an error.
    <table>
      <tr>
	<th align="left">Response:</th>
	<td>${status}</td>
      </tr>
      <tr>
	<th align="left">Request:</th>
	<td>${url}</td>
      </tr>
    </table>
</script>

We could create the following error handler:

function access_error( errorDetails )
{
    $('#error-dialog').empty();

    $( "#errorTemplate" ).template( "errorTemplate" );
    $.tmpl( "errorTemplate", errorDetails ).appendTo( "#error-dialog" );

    $('#error-dialog').dialog('open');
}

Notice that the error handler is passed a errorDetails object that contains lots of different values about the error:

Now we can associate the error handler with all errors, with:

$.fuzzytoast.default_error = access_error;

loadWithCache()

jQuery has a nice function, .load() which loads some static HTML data and inserts in the page. The problem is if you do this process again, it re-downloads it.

We've extended jQuery with a .loadWithCache() function that acts just like .load() the first time it is executed. If it is called again, it just pulls the results from an in-memory cache, and doesn't bother hitting the server.

This function is useful for static HTML files that you know won't change very often.

The behavioral differences between the first and *second load* include:

Note: The cache is cleared when the browser page is refreshed.