Created
September 13, 2012 11:29
-
-
Save cyrusbeer/3713706 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(function( $ ) { | |
$(document).ready(function() { | |
$(".ajax-intercept").ajaxInterceptor({ | |
pageElementToUpdateSelector: "div#content", | |
showLoadingMessage: true, | |
showLoadingDelayMillis: 600, | |
loadingMessage: 'Loading...', | |
loadingMessageSelector: 'div.loading-message' | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Author: Cyrus Beer | |
* 9/13/2012 | |
* Requires: history.js, history.adapter.jquery.js, json2.js | |
*/ | |
(function($) { | |
var settings = { | |
'pageElementToUpdateSelector' : undefined, // The selector for the page element that will be updated | |
'showLoadingMessage' : true, | |
'loadingMessageDelay': 600, // with these defaults, if the ajax call takes > .6 seconds, a loading message will show until the ajax call completes. | |
'loadingMessage': 'Loading...', | |
'loadingMessageSelector': 'div.loading-message' | |
}; | |
var History = null; | |
var selector = ''; | |
var lastUrlLoaded; | |
var methods = { | |
init : function(options) { // Initializes the plugin | |
selector = this.selector; | |
if (options) { | |
$.extend(settings, options); | |
} | |
if (settings.pageElementToUpdateSelector === null) { | |
$.error('Missing required parameter pageElementToUpdateSelector on jQuery.ajaxInterceptor'); | |
return; | |
} | |
if (methods.supported()) { | |
methods.bindEvents.call($(this)); | |
} | |
return $(this); | |
}, | |
// If the browser does not support HTML 5, the ajax interceptor does not get called | |
// so it degrades nicely. | |
supported: function() { | |
History = window.History; | |
return History.enabled; | |
}, | |
bindEvents: function() { | |
$(selector).off('click').on('click', function(e) { | |
e.preventDefault(); | |
// allow a link to override the pageElementToUpdateSelector if need be. | |
if ($(this).attr('pageElementToUpdateSelector')) { | |
settings.pageElementToUpdateSelector = $(this).attr('pageElementToUpdateSelector'); | |
} | |
var url = $(this).attr('href'); | |
History.pushState({url:url}, '', url); | |
return false; | |
}); | |
// Bind state change for preserving back/forwards browser button functionality when loading ajax | |
History.Adapter.bind(window, 'statechange', function(e) { | |
var state = History.getState(); | |
if (state !== null && state.url != lastUrlLoaded) { | |
methods.loadContent(state.url); | |
lastUrlLoaded = state.url; | |
} | |
}); | |
}, | |
// Loads the ajax content | |
loadContent: function(url) { | |
var destination = $(settings.pageElementToUpdateSelector); | |
$.ajax({ | |
url:url, | |
data: {'page_element_to_update_selector':settings.pageElementToUpdateSelector}, | |
method:'GET', | |
beforeSend: function(xhr) { | |
if (settings.showLoadingMessage === true) { | |
$.showLoadingMessage({ | |
delay:settings.loadingMessageDelay, | |
message:settings.loadingMessage, | |
selector:settings.loadingMessageSelector | |
}); | |
} | |
}, | |
complete: function(xhr, status) { | |
if (settings.showLoadingMessage === true) { | |
$.hideLoadingMessage({selector:settings.loadingMessageSelector}); | |
} | |
}, | |
success: function(ajaxHtml) { | |
destination.html(ajaxHtml); | |
document.title = $(ajaxHtml).filter("div#page_title").text(); | |
if (typeof settings.ready == 'function') { // Fire the callback | |
settings.ready.call($(this), url); | |
} | |
}, | |
// on error, send the url to the browser, so the error will be clearly visible | |
error: function(jqXHR, textStatus, errorThrown) { | |
window.location = url; | |
} | |
}); | |
} | |
}; | |
$.fn.ajaxInterceptor = function(method) { | |
if (methods[method]) { | |
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); | |
} | |
else if (typeof method === 'object' || !method) { | |
return methods.init.apply(this, arguments); | |
} | |
else { | |
$.error('Method ' + method + ' does not exist on jQuery.ajaxInterceptor'); | |
} | |
}; | |
$.showLoadingMessage = function(optionsOverride){ | |
var options = { | |
message:'Loading...', | |
delay: 0, | |
selector: undefined | |
}; | |
$.extend(options, optionsOverride); | |
if (options.delay > 0) { | |
$(document).data("_loading_timeout", setTimeout(function() { $.showLoadingMessageNow(options)}, options.delay)); | |
} else { | |
$.showLoadingMessageNow(options); | |
} | |
}; | |
$.showLoadingMessageNow = function(options){ | |
//if this element has delayed mask scheduled then remove it and display the new one | |
if ($(document).data("_loading_timeout") !== undefined) { | |
clearTimeout($(document).data("_loading_timeout")); | |
$(document).removeData("_loading_timeout"); | |
} | |
$(options.selector) | |
.html(options.message) | |
.show(); | |
}; | |
$.hideLoadingMessage = function(options){ | |
//if this element has delayed mask scheduled then remove it | |
if ($(document).data("_loading_timeout") !== undefined) { | |
clearTimeout($(document).data("_loading_timeout")); | |
$(document).removeData("_loading_timeout"); | |
} | |
$(options.selector).hide(); | |
}; | |
})(jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#{if (!params.page_element_to_update_selector)} | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>#{get 'title' /}</title> | |
<meta charset="${_response_encoding}"> | |
#{stylesheet 'main.css' /} | |
#{stylesheet 'bootstrap.min.css' /} | |
#{/if} | |
#{get 'moreStyles' /} | |
#{if (!params.page_element_to_update_selector)} | |
<link rel="shortcut icon" type="image/png" href="@{'/public/images/favicon.png'}"> | |
#{script 'jquery-1.8.1.min.js' /} | |
#{script 'history.js' /} | |
#{script 'history.adapter.jquery.js' /} | |
#{script 'json2.js' /} | |
#{script 'jquery.ajax.interceptor.js' /} | |
#{script 'application.js' /} | |
#{/if} | |
#{get 'moreScripts' /} | |
#{if (!params.page_element_to_update_selector)} | |
</head> | |
<body> | |
<div class="navbar"> | |
<div class="navbar-inner"> | |
<a class="brand" href="#">Company XYZ</a> | |
<ul class="nav"> | |
<li name="heading1" class="active"><a href="/" class="ajax-intercept">Heading 1</a></li> | |
<li name="heading2"><a href="/page2" class="ajax-intercept">Heading 2</a></li> | |
</ul> | |
</div> | |
</div> | |
<div class="loading-message"></div> | |
<div class="container" id="content"> | |
#{/if} | |
<div style="display:none" id="page_title">#{get 'title' /}</div> | |
#{doLayout /} | |
#{if (!params.page_element_to_update_selector)} | |
</div> | |
</body> | |
</html> | |
#{/if} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#{extends 'main.html' /} | |
#{set title:'Page 2' /} | |
#{set 'moreScripts'} | |
#{script 'script-to-load-only-on-this-page.js' /} | |
#{/set} | |
<script type="text/javascript"> | |
$(document).ready(function() { | |
$("div.navbar-inner li.active").removeClass("active"); | |
$("div.navbar-inner li[name='heading2']").addClass("active"); | |
}); | |
</script> | |
<h2>Page 2</h2> | |
<br/><br/> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment