A Sexy Sequential Ajax (Sajax) Javascript Library for jQuery
JavaScript PHP

README.textile

Sexy.js

View the Demo at SexyJS.com

Sexy.js is a lightweight JavaScript library which provides a sleek facade and enhanced Sequential Ajax (Sajax) functionality to jQuery’s native Ajax methods.

Sequential Ajax, or Sajax, is an Ajax design pattern where related asynchronous XMLHttpRequests are made simultaneously and their callbacks fired in a specified sequence, regardless of the order in which they return, with each callback function receiving the return value of the previous callback function as an additional argument.

The Sajax pattern simplifies and speeds the loading of scripts, stylesheets, and data, while facilitating the combination and manipulation of data from multiple sources without complicated workarounds to handle the implicit timing issues of Ajax’s asynchronous nature.

And Sexy.js makes it look good.

Damn good.

Ugly

<script src="/js/jquery.template.min.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="css/comments.css" type="text/css" media="screen" charset="utf-8"/>

<script type="text/javascript" charset="utf-8">

$.get('comments.tpl', function (tpl) {
  $.getJSON('comments.json', function (data) {
    $.template(tpl, data).appendTo('#comments');
  });
});

</script>

Sexy

<script type="text/javascript" charset="utf-8">

Sexy
  .js('/js/jquery.template.min.js')
  .css('css/comments.css')
  .text('comments.tpl')
  .json('comments.json', function (data, status, tpl) {
    $.template(tpl, data).appendTo('#comments');
  });
  
</script>

Sexy provides a chainable API for loading each of the data types supported by jQuery’s native Ajax methods:

  • html (url, callback)
  • json (url, callback)
  • jsonp (url, callback)
  • script (url, callback)
  • text (url, callback)
  • xml (url, callback)

as well as one additional method for loading CSS (local file access only):

  • style (url, callback)

and two aliases for sex appeal:

  • js (url, callback) // → script
  • css (url, callback) // → style

Each of the above methods can take either a url and optional callback as argument or a single ajaxSetup config object (see jQuery documentation).

All callbacks receive three arguments: data and status (from jQuery’s native functionality) and previous which is the return value of the previously executed callback.

If no callback is supplied for any of the data carrying calls (html, json, jsonp, text, xml), a pass-through function automagically returns the request data to the next callback.

Sexy
  .js('/js/jquery.template.min.js')
  .css('css/comments.css')
  
  // Note there is no callback...
  .text('comments.tpl')
  
  // ...yet the tpl appears over here!
  .json('comments.json', function (data, status, tpl) {
    $.template(tpl, data).appendTo('#comments');
  });

If no callback is supplied for the two non-data carrying calls (script/js, style/css) or setup, a pass-through function automagically returns the most recently returned value.

Sexy
  
  // Note there is no callback...
  .text('comments.tpl')

  // ...none here either...
  .js('/js/jquery.template.min.js')
  
  // ...or here...
  .css('css/comments.css')
  
  // ...yet the tpl appears over here!
  .json('comments.json', function (data, status, tpl) {
    $.template(tpl, data).appendTo('#comments');
  });

You can also set a default configuration for successive calls:

  • setup (cfg)

setup can be used anywhere in the chain to change the default configuration. Passing no arguments will remove any previously configured options.

Sexy also has an additional method for bundling packaged scripts:

  • bundle (url , url2, …, callback)

The bundle method loads multiple scripts as text and, once all requests are complete, makes a single script injection, and then fires the optional callback. This method is useful for maintaining JavaScript in packages in an environment that doesn’t support or necessitate a server-side bundling solution.

More examples

Binding
Sexy
  .json('ticketingData.json', function (data) {
    return data.ticketingInfo;
  })
  .json('gameData.json', function (data, status, ticketingInfo) {
    for (var i = 0, n = data.games.length; i < n; ++i) {
      data.games[i].ticketingInfo = ticketingInfo[data.games[i].id];
    }
    // render games...
  });

Bootstrapping
Sexy
  .js('js/jquery.template.min.js')
  .css('css/comments.css')
  .text('comments.tpl', function (data, status, previous) {
    return data;
  })
  .json({
    url: 'comments.json',
    data: { articleId: 123 },
    success: function (data, status, previous) {
      $.template(previous, data).appendTo('#comments');
    }
  });

Bundling
Sexy
  .bundle(
    'mlb.js',
    'mlb.stats.js',
    'mlb.stats.widget.js',
    'mlb.stats.widget.LeagueSelector.js',
    'mlb.stats.widget.StatTypeSelector.js',
    'mlb.stats.app.js',
    'mlb.stats.app.SortableStats.js',
    function () {
      mlb.stats.app.SortableStats.init();
    }
  );

History

The original goal when designing $.sajax, the predecessor to Sexy, was a simple pattern for executing and handling multiple Ajax requests. But by building upon jQuery’s robust Ajax framework, $.sajax also coincidentally achieved the goal of parallel asynchronous script loading, a performance optimization similar to those found in Kyle Simpson’s LABjs and Steve Souders’ EFWS. However, neither $.sajax nor Sexy are currently designed for optimal performance. For pure performance, use either of these two more mature examples. Sexy’s dependency on jQuery results in a slight performance hit. For convenience and style with substance, use Sexy.js.

NOTE: The library is just entering beta, but is currently in use on MLB.com’s 2010 website (in development). Stay tuned for more…