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