views:

297

answers:

2

I want to store key/value pairs in URI's after the hash for use on the client side like so:

http://www.foo.com/index.html#foo=bar&baz=quux

Is there a pre-existing solution that already does this or should I roll my own? I'm already using JQuery so a JQuery solution would be particularly welcome.

My original idea was to use a regex, but that gets complicated, especially when you add the need to escape both keys and values.

EDIT: Let me clarify. I want to do something like this:

foo = hash.get('foo');
hash.set('bar','baz');
+1  A: 

You can store JSON data after the hash. I've been looking into doing that - it'd avoid the parsing, although you may open yourself up to tampering.

Jon Galloway
That's a little more heavyweight than I wanted; key/value pairs are all that is necessary. In the absence of a cleaner option I might go with this, though, just for the benefit of being able to use a prepackaged option. We'll see.
Imagist
+2  A: 

For anyone interested, here's the solution I came up with:

/**
 * Copyright 2009 by David Kerkeslager
 * Released under the BSD License (http://davidkerkeslager.com/license.txt).
 *
 * This library defines an object-literal which allows one to store key/value pairs after the hash (#) in the URI.
 * The syntax of the storage is modeled after the way that GET variables are stored after the question mark (?) in
 * the URI.
 *
 * Example URI: "http://www.foo.com/index.html#foo=bar&baz=quux"
 *
 * Note: it should be obvious that this should not be used for storing private data of any kind.
 */

var URIHash =
{
 /**
  * Dump the contents of the URI hash into an associative array. If the hash is invalid, the method returns
  * undefined.
  */
 dump : function()
 {
  var hash = document.location.hash;
  var dump = new Array();

  if(hash.length == 0) return dump;

  hash = hash.substring(1).split('&');

  for(var key in hash)
  {
   var pair = hash[key].split('=');

   if(pair.length != 2 || pair[0] in dump)
    return undefined;

   // escape for storage
   dump[unescape(pair[0])] = unescape(pair[1]);
  }

  return dump;
 },

 /**
  * Takes an associative array and stores it in the URI as a hash after the # prefix, replacing any pre-
  * existing hash.
  */
 load : function(array)
 {
  var first = true;
  var hash = '';

  for(var key in array)
  {
   if(!first) hash += '&';
   hash += escape(key) + '=' + escape(array[key]);
  }

  document.location.hash = hash;
 },

 /**
  * Get the value of a key from the hash.  If the hash does not contain the key or the hash is invalid,
  * the function returns undefined.
  */
 get : function(key)
 {
  return this.dump()[key];
 },

 /**
  * Set the value of a key in the hash.  If the key does not exist, the key/value pair is added.
  */
 set : function(key,value)
 {
  var dump = this.dump();
  dump[key] = value;

  var hash = new Array();

  for(var key in dump)
   hash.push(escape(key) + '=' + escape(dump[key]));

  document.location.hash = hash.join('&');
 }
}
Imagist