Siegfried Puchbauer
2006-May-12 14:18 UTC
draft-proposal for Ajax.History - History/Bookmark handling in Ajax apps
Hi list,
In one of my previous projects I had to satisfy the requirement of handling
browser back- and forward calls within an Ajax application. Thus I
didn''t
get an urge to switch the JS part of this project to an other framework like
dojo (which supports Browser history handling out-of-the-box), I had to come
up with an idea of doing this with prototype/scriptaculous.
The arisen source code:
Ajax.History = {
initialize: function(options) {
this.options = Object.extend({
interval: 200
},options||{});
this.callback = this.options.callback || Prototype.emtpyFunction;
if(navigator.userAgent.toLowerCase().indexOf(''msie'')
> 0)
this.locator = new
Ajax.History.Iframe(''ajaxHistoryHandler'',
this.options.iframeSrc);
else
this.locator = new Ajax.History.Hash();
this.currentHash = '''';
this.locked = false;
},
add: function(hash) {
this.locked = true;
clearTimeout(this.timer);
this.currentHash = hash;
this.locator.setHash(hash);
this.timer = setTimeout(this.checkHash.bind(this),
this.options.interval);
this.locked = false;
},
checkHash: function(){
if(!locked){
var check = this.locator.getHash();
if(check != this.currentHash){
this.callback(check);
this.currentHash = check;
}
}
this.timer = setTimeout(this.checkHash.bind(this),
this.options.interval);
},
getBookmark: function(){
return this.locator.getBookmark();
}
}
// Hash Handler for IE (Tested with IE6)
Ajax.History.Iframe = Class.create();
Ajax.History.Iframe.prototype = {
initialize: function(id, src) {
this.url = '''';
this.id = id || ''ajaxHistoryHandler'';
this.src = src || '''';
document.write(''<iframe
src="''+this.src+''"
id="''+this.id+''"
name="''+this.id+''" style="display: none;"
></iframe>'');
},
setHash: function(hash){
try {
$(this.id).setAttribute(''src'', this.src +
''?'' + hash);
}catch(e) {}
window.location.href = this.url + ''#'' + hash;
},
getHash: function(){
try {
return (document.frames[this.id
].location.href||''?'').split(''?'')[1];
}catch(e){ return ''''; }
},
getBookmark: function(){
try{
return
window.location.href.split(''#'')[1]||'''';
}catch(e){ return ''''; }
}
}
// Hash Handler for a modern browser (tested with firefox 1.5)
Ajax.History.Hash = Class.create();
Ajax.History.Hash.prototype = {
initialize: function(){
},
setHash: function(hash){
window.location.hash = hash;
},
getHash: function(){
return window.location.hash.substring(1)||'''';
},
getBookmark: function(){
try{
return window.location.hash.substring(1)||'''';
}catch(e){ return ''''; }
}
}
Sample Usage:
first you have to define a callback method for the history handler which
replays a previous ajax request:
var historyUpdate = function(hash) {
new Ajax.Request(
....
}
in the onSuccess/onComplete of a Ajax.Request or Ajax.Updater (etc) you have
to add an history point:
var handleSuccess = function(request){
//... update DOM or smth like that
Ajax.History.add(request.options.parameters)
//...
}
(might also be done an Ajax.Responder or something like that)
and in the foot of your html page you have to insert smth like:
<script type="text/javascript">
// <![CDATA[
var historyHandler = Ajax.History.initialize({
callback: historyUpdate,
iframeSrc: ''http://url.of.an/empty/page.html''
});
// ]]>
</script>
Explanation:
The Ajax.History object periodically (defined by the option intervall)
checks the hash object for a change. There are currently 2 implementations
for this hash object. iframe based for IE and window.location.hash based for
firefox/mozilla. When the hash changes the callback function gets called
with the changed hash as arguement. History entries are added with
Ajax.History.add(''a_new_hash'').
This is a very simple implementation of history support and needs to be
radically extended to be usefull ;)
So any ideas, proposals, hints or something like that are greaty appreceated
I will set up a test page and unit tests when I can spare some time for
it...
best regards
--
Mit freundlichen Grüßen
Siegfried Puchbauer
_______________________________________________
Rails-spinoffs mailing list
Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
