Skip to content

Instantly share code, notes, and snippets.

@georgebrock
Created September 29, 2011 21:55
Show Gist options
  • Save georgebrock/1252052 to your computer and use it in GitHub Desktop.
Save georgebrock/1252052 to your computer and use it in GitHub Desktop.
bindWithPreload jQuery plugin
// jQuery extension to bind events that depend on an AJAX request.
//
// As soon as the event is bound it will start preloading the data from the server.
// If the event occurs while the data is still loading, your callback will be called
// as soon as the data finishes loading.
//
// Example:
// $('a.more').bindWithPreload('click', '/foo.json', function(data) {
// alert(data.message);
// });
//
// You can also specify additional callbacks:
// $('a.more').bindWithPreload('click', '/foo.json', {
// action: function(data) {
// // This will be called when the event fires and the data is available
// },
// wait: function() {
// // This will be called when the event fires and the data is not loaded yet
// // If the data loads sucessfully it will be followed by "loaded" and "action",
// // if the data fails to load it will be followed by "error".
// },
// loaded: function(data) {
// // This will be called when the data finishes loading sucessfully.
// // It can be used to clean up after the "wait" callback.
// },
// error: function(jqXHR, textStatus, errorThrown) {
// // This will be called if the data fails to load.
// // See the jQuery.ajax documentation for details.
// // The element will be bound to `this`
// }
// });
(function($) {
$.fn.bindWithPreload = function(event, url, options) {
var element = this,
actionFunc = typeof options == 'function' ? options : options.action,
waitFunc = options.wait || $.noop,
loadedFunc = options.loaded || $.noop,
errorFunc = options.error || $.noop,
immediate = false,
setImmediate = function() {
waitFunc();
immediate = true;
};
// When the event is triggered, set the immediate flag so we know
// to fire it as soon as the preload is finished.
element.bind(event, setImmediate);
// Begin the preload.
jQuery.ajax({
url: url,
context: element,
error: function() {
element.unbind(event, setImmediate);
errorFunc.apply(element, arguments);
},
success: function(data) {
loadedFunc(data);
// Re-bind the event.
element
.unbind(event, setImmediate)
.bind(event, function() {
return actionFunc(data);
});
// If the event occured while we were waiting, we should
// trigger it immediately.
if(immediate) {
element.trigger(event);
}
}
});
return this;
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment