<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Code in the hole (Entries tagged as javascript)</title>
    <link>http://codeinthehole.com/</link>
    <description>David Winterbottom</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.3.1 - http://www.s9y.org/</generator>
    
    

<item>
    <title>Javascript refactoring for customising shared libraries</title>
    <link>http://codeinthehole.com/archives/30-Javascript-refactoring-for-customising-shared-libraries.html</link>
            <category>Development</category>
    
    <comments>http://codeinthehole.com/archives/30-Javascript-refactoring-for-customising-shared-libraries.html#comments</comments>
    <wfw:comment>http://codeinthehole.com/wfwcomment.php?cid=30</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://codeinthehole.com/rss.php?version=2.0&amp;type=comments&amp;cid=30</wfw:commentRss>
    

    <author>nospam@example.com (David Winterbottom)</author>
    <content:encoded>
    &lt;p&gt;
One difficulty working with a shared in-house framework is it is difficult to maintain a common javascript file that is valid across multiple applications.  This is currently an issue we face at Tangent, where we run a generic e-commerce platform which we customise to the needs of each client.  Most of these e-commerce applications have a javascript-rich checkout page whose functionality differs in small yet significant ways such as the required and optional fields within a delivery address, or the range of delivery options available.  Ideally, you would have a single javascript file to work for all these checkouts, but these differences make such a file impracticle due to the changes in DOM structure and business logic between applications.   
&lt;/p&gt;
&lt;p&gt;
For instance, one problem that arose recently was a requirement to remove the javascript messaging from within certain parts of the checkout for one appliation.  The shared &lt;tt&gt;checkout.js&lt;/tt&gt; file features a method which reloads the order totals within the page after a new delivery option has been chosen and displays a message to notify the user:
&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;// [checkout.js]
var shop = {
    checkout: {
        reloadOrderTotals: function() {
            // Do the reloading...
            shop.display.notify(&quot;Order totals recalculating...&quot;);
        }
}
&lt;/code&gt;
&lt;p&gt;
Unfortunately, another client required the same functionality to reload the order totals but without the notification call.  One option would have been to create a local version of the &lt;code&gt;checkout.js&lt;/code&gt; file and remove the offending line, but this would have created a larger maintenance overhead going forward due to the large amount of duplicate code.
&lt;/p&gt;
&lt;p&gt;A neater option would have been to dynamically override the &lt;code&gt;shop.checkout.reloadOrderTotals&lt;/code&gt; method in an application-specific file:  
&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;// [application.js]
shop.checkout.reloadOrderTotals = function() {
    // Reload order totals but without a notification call
}
&lt;/code&gt;
&lt;p&gt;
However, again this leads to most of the the body of the &lt;code&gt;shop.checkout.reloadOrderTotals&lt;/code&gt; method being duplicated just to remove one line.  
&lt;p&gt;
Instead, drawing inspiration from the excellent &lt;em&gt;Working with Legacy Code&lt;/em&gt; by Michael Flowers, a neater solution is to perform a dynamic-language version of the &lt;em&gt;Extract method&lt;/em&gt; refactoring to isolate the functionality that we wanted to override into it&#039;s own method.  Hence, we alter &lt;code&gt;checkout.js&lt;/code&gt; to split the reloading and notification functionality into two methods:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;// [checkout.js]
var shop = {
    checkout: {
        reloadOrderTotals: function() {
             // Do the reloading...
            shop.checkout.displayOrderTotalNotification(&quot;Order totals recalculating...&quot;);
        },
        displayOrderTotalNotification(message) {
            shop.display.notify(message);
        } 
}
&lt;/code&gt;
&lt;p&gt;
Now in the local project javascript file, we can null out the messaging behaviour:
&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;// [application.js]
shop.checkout.displayOrderTotalNotification = function(){}
&lt;/code&gt;
&lt;p&gt;
This neat trick allows us to customise our core javascript functionality in a way that does not lead to code duplication.  The only thing required to make this work is to ensure that the shared checkout file is loaded before the application-specific one.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 13 Oct 2009 22:48:42 +0000</pubDate>
    <guid isPermaLink="false">http://codeinthehole.com/archives/30-guid.html</guid>
    <category>javascript</category>
<category>refactoring</category>

</item>
<item>
    <title>Auto-generating an FAQ with Prototype</title>
    <link>http://codeinthehole.com/archives/28-Auto-generating-an-FAQ-with-Prototype.html</link>
            <category>Tidbits</category>
    
    <comments>http://codeinthehole.com/archives/28-Auto-generating-an-FAQ-with-Prototype.html#comments</comments>
    <wfw:comment>http://codeinthehole.com/wfwcomment.php?cid=28</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://codeinthehole.com/rss.php?version=2.0&amp;type=comments&amp;cid=28</wfw:commentRss>
    

    <author>nospam@example.com (David Winterbottom)</author>
    <content:encoded>
    &lt;p&gt;Have just been writing an FAQ page for &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.commandlinefu.com&#039;);&quot;  href=&quot;http://www.commandlinefu.com&quot;&gt;commandlinefu.com&lt;/a&gt;.  Documenting is always tiresome, but FAQs particularly so when hand-coding the HTML links between each question and the summary table at the top of the page.&lt;/p&gt;
&lt;p&gt;Javascript to the rescue: I cobbled together a quick Prototype script which automatically generates the FAQ summary links by parsing the DOM for the appropriate links:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;document.observe(&#039;dom:loaded&#039;, function(){
    $$(&#039;a.question&#039;).each(function(ele){
        var id = ele.innerHTML.unescapeHTML().gsub(/[^\w- ]/, &#039;&#039;).gsub(/[\s-]+/, &#039;-&#039;).toLowerCase();
        ele.writeAttribute({id: id});
        var link = new Element(&#039;a&#039;, {href: &#039;#&#039;+id})
            .update(ele.innerHTML)
            .observe(&#039;click&#039;, function(event){
                event.stop();
                Effect.ScrollTo(ele); 
            });
        $(&#039;questions&#039;).insert(new Element(&#039;li&#039;).insert(link));
    });
});&lt;/code&gt;
&lt;p&gt;Now, all I have to do is write my FAQ ensuring the questions live in anchor tags with the class &quot;question&quot; and there is an empty list tag at the top of the page to house the summary block.&lt;/p&gt;
&lt;p&gt;Here&#039;s two snapshots the relevant section of the DOM before and after the &lt;code&gt;dom:loaded&lt;/code&gt; event has fired.  Before:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;&amp;lt;ul id=&quot;questions&quot;&gt;&amp;lt;/ul&gt;
&amp;lt;dl&gt;
    &amp;lt;dt&gt;&amp;lt;a class=&quot;question&quot;&gt;What is this site?&amp;lt;/a&gt;&amp;lt;/dt&gt;
    &amp;lt;dd&gt;...&amp;lt;/dd&gt;
    &amp;lt;dt&gt;&amp;lt;a class=&quot;question&quot;&gt;Who created this site?&amp;lt;/a&gt;&amp;lt;/dt&gt;
    &amp;lt;dd&gt;...&amp;lt;/dd&gt;
&amp;lt;/dl&gt;&lt;/code&gt;
&lt;p&gt;and after:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;&amp;lt;ul id=&quot;questions&quot;&gt;
    &amp;lt;li&gt;&amp;lt;a href=&quot;#what-is-this-site&quot;&gt;What is this site?&amp;lt;/a&gt;&amp;lt;/li&gt;
    &amp;lt;li&gt;&amp;lt;a href=&quot;#who-created-this-site&quot;&gt;Who created this site?&amp;lt;/a&gt;&amp;lt;/li&gt;
&amp;lt;/ul&gt;
&amp;lt;dl&gt;
    &amp;lt;dt&gt;&amp;lt;a class=&quot;question&quot; id=&quot;what-is-this-site&quot;&gt;What is this site?&amp;lt;/a&gt;&amp;lt;/dt&gt;
    &amp;lt;dd&gt;...&amp;lt;/dd&gt;
    &amp;lt;dt&gt;&amp;lt;a class=&quot;question&quot; id=&quot;who-created-this-site&quot;&gt;Who created this site?&amp;lt;/a&gt;&amp;lt;/dt&gt;
    &amp;lt;dd&gt;...&amp;lt;/dd&gt;
&amp;lt;/dl&gt;&lt;/code&gt;
&lt;p&gt;As you can see, the javascript simply extracts the relevant content from the questions and inserts the appropriate identities and links into the DOM to form the quick-links.  
Using the &lt;code class=&quot;prettyprint&quot;&gt;Effect.ScrollTo&lt;/code&gt; function also gives a pleasant user experience.&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Mon, 25 May 2009 20:34:01 +0000</pubDate>
    <guid isPermaLink="false">http://codeinthehole.com/archives/28-guid.html</guid>
    <category>commandlinefu</category>
<category>javascript</category>
<category>prototype</category>

</item>
<item>
    <title>Inspecting Javascript objects</title>
    <link>http://codeinthehole.com/archives/12-Inspecting-Javascript-objects.html</link>
            <category>Development</category>
    
    <comments>http://codeinthehole.com/archives/12-Inspecting-Javascript-objects.html#comments</comments>
    <wfw:comment>http://codeinthehole.com/wfwcomment.php?cid=12</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://codeinthehole.com/rss.php?version=2.0&amp;type=comments&amp;cid=12</wfw:commentRss>
    

    <author>nospam@example.com (David Winterbottom)</author>
    <content:encoded>
    &lt;p&gt;Learning Ruby or Python from the command-line prompt is greatly enhanced by the built-in inspection methods these languages provide.  These allow the methods and properties of an object to be interrogated via a simple method call which returns an array of all property or method names.&lt;/p&gt;
&lt;p&gt;For instance, in IRB (the interactive Ruby command-line) we can interrogate the integer object:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;irb(main):001:0&gt;my_int = 1
irb(main):002:0&gt;my_int.methods&lt;/code&gt;
&lt;p&gt;This returns an array of all method names for integer objects:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;[&quot;%&quot;, &quot;odd?&quot;, &quot;inspect&quot;, &quot;prec_i&quot;, &quot;&lt;&lt;&quot;, &quot;tap&quot;, &quot;div&quot;, &quot;&amp;&quot;, &quot;clone&quot;, &quot;&gt;&gt;&quot;, &quot;public_methods&quot;, &quot;&lt;u&gt;_send_&lt;/u&gt;&quot;, &quot;object_id&quot;, &quot;instance_variable_defined?&quot;, &quot;equal?&quot;, &quot;freeze&quot;, &quot;to_sym&quot;, &quot;*&quot;, &quot;ord&quot;, &quot;+&quot;, &quot;extend&quot;, &quot;next&quot;, &quot;send&quot;, &quot;round&quot;, &quot;methods&quot;, &quot;prec_f&quot;, &quot;-&quot;, &quot;even?&quot;, &quot;singleton_method_added&quot;, &quot;divmod&quot;, &quot;hash&quot;, &quot;/&quot;, &quot;integer?&quot;, &quot;downto&quot;, &quot;dup&quot;, &quot;to_enum&quot;, &quot;instance_variables&quot;, &quot;|&quot;, &quot;eql?&quot;, &quot;size&quot;, &quot;instance_eval&quot;, &quot;truncate&quot;, &quot;~&quot;, &quot;id&quot;, &quot;to_i&quot;, &quot;singleton_methods&quot;, &quot;modulo&quot;, &quot;taint&quot;, &quot;zero?&quot;, &quot;times&quot;, &quot;instance_variable_get&quot;, &quot;frozen?&quot;, &quot;enum_for&quot;, &quot;display&quot;, &quot;instance_of?&quot;, &quot;^&quot;, &quot;method&quot;, &quot;to_a&quot;, &quot;+@&quot;, &quot;-@&quot;, &quot;quo&quot;, &quot;instance_exec&quot;, &quot;type&quot;, &quot;**&quot;, &quot;upto&quot;, &quot;to_f&quot;, &quot;&lt;&quot;, &quot;step&quot;, &quot;protected_methods&quot;, &quot;&lt;=&gt;&quot;, &quot;between?&quot;, &quot;==&quot;, &quot;remainder&quot;, &quot;&gt;&quot;, &quot;===&quot;, &quot;to_int&quot;, &quot;nonzero?&quot;, &quot;pred&quot;, &quot;instance_variable_set&quot;, &quot;coerce&quot;, &quot;respond_to?&quot;, &quot;kind_of?&quot;, &quot;floor&quot;, &quot;succ&quot;, &quot;&gt;=&quot;, &quot;prec&quot;, &quot;to_s&quot;, &quot;&lt;=&quot;, &quot;fdiv&quot;, &quot;class&quot;, &quot;private_methods&quot;, &quot;=~&quot;, &quot;tainted?&quot;, &quot;&lt;u&gt;_id_&lt;/u&gt;&quot;, &quot;abs&quot;, &quot;untaint&quot;, &quot;nil?&quot;, &quot;chr&quot;, &quot;id2name&quot;, &quot;is_a?&quot;, &quot;ceil&quot;, &quot;[]&quot;]&lt;/code&gt;
&lt;p&gt;Meanwhile, in Python we use the build-in function dir():&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;&gt;&gt;&gt; my_dict = {}
&gt;&gt;&gt; dir(my_dict)&lt;/code&gt;
&lt;p&gt;to get a list of attributes (including methods) for a dictionary variable:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;[&#039;&lt;u&gt;_class_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_cmp_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_contains_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_delattr_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_delitem_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_doc_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_eq_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_ge_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_getattribute_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_getitem_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_gt_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_hash_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_init_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_iter_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_le_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_len_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_lt_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_ne_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_new_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_reduce_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_reduce_ex_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_repr_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_setattr_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_setitem_&lt;/u&gt;&#039;, &#039;&lt;u&gt;_str_&lt;/u&gt;&#039;, &#039;clear&#039;, &#039;copy&#039;, &#039;fromkeys&#039;, &#039;get&#039;, &#039;has_key&#039;, &#039;items&#039;, &#039;iteritems&#039;, &#039;iterkeys&#039;, &#039;itervalues&#039;, &#039;keys&#039;, &#039;pop&#039;, &#039;popitem&#039;, &#039;setdefault&#039;, &#039;update&#039;, &#039;values&#039;]&lt;/code&gt;
&lt;p&gt;Javascript doesn&#039;t provide such a feature as standard but it&#039;s straightforward to implement a simple inspection object:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot; style=&quot;white-space:nowrap&quot;&gt;var Inspect = {
    TYPE_FUNCTION: &#039;function&#039;,
    // Returns an array of (the names of) all methods
    methods: function(obj) {
        var testObj = obj || self;
        var methods = [];
        for (prop in testObj) {
            if (typeof testObj[prop] == Inspect.TYPE_FUNCTION &amp;&amp;amp; typeof Inspect[prop] != Inspect.TYPE_FUNCTION) {
                methods.push(prop);
            }
        }
        return methods;
    },
    // Returns an array of (the names of) all properties
    properties: function(obj) {
        var testObj = obj || self;
        var properties = [];
        for (prop in testObj) {
            if (typeof testObj[prop] != Inspect.TYPE_FUNCTION &amp;&amp;amp; typeof Inspect[prop] != Inspect.TYPE_FUNCTION) {
                properties.push(prop);
            }
        }
        return properties;
    }
}&lt;/code&gt;
&lt;p&gt;Now we can simply pass in any object (or call without an argument to test the window object) to retrieve an array or properties or methods.   For example, working at the Firebug console, we can examine the hash object of the Prototype Javascript library, and the native document.location object:&lt;/p&gt;
&lt;img src=&quot;http://codeinthehole.com/app/images/firebug-screenshot.png&quot; /&gt;
&lt;p&gt;Moreover, it can sometimes be useful to have a debug mode for an application where these methods are added to the supertype &quot;object&quot; which provides the prototype for all others.  In this instance, debug mode is switched on by added a &#039;debug_mode&#039; parameter to the GET parameters.  For convenience, I&#039;m also using the methodize function provided by Prototype:&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;if (/[?&amp;]debug_mode(&amp;.*)?$/.test(document.location.search)) {
    Object.prototype.properties = Inspect.properties.methodize();
    Object.prototype.methods = Inspect.methods.methodize();
}&lt;/code&gt;
&lt;p&gt;Then you can inspect an object without refering to the Inspect object (namespace really):&lt;/p&gt;
&lt;code class=&quot;prettyprint&quot;&gt;var my_hash = new Hash();
my_hash.methods();
my_hash.properties()&lt;/code&gt;
&lt;p&gt;
Code and associated JSunit test suite available at &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/github.com/codeinthehole/js-nuggets/&#039;);&quot;  href=&quot;http://github.com/codeinthehole/js-nuggets/&quot;&gt;my github repo&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;Further reading&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/yodayid.blogspot.com/2007/05/ruby-tip-cleaner-object-inspection.html&#039;);&quot;  href=&quot;http://yodayid.blogspot.com/2007/05/ruby-tip-cleaner-object-inspection.html&quot;&gt;Ruby Tip - Cleaner Object Inspection - YodaYid&#039;s WackyWorld&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt; 
    </content:encoded>

    <pubDate>Sun, 24 May 2009 12:04:00 +0000</pubDate>
    <guid isPermaLink="false">http://codeinthehole.com/archives/12-guid.html</guid>
    <category>javascript</category>
<category>prototype</category>
<category>python</category>
<category>ruby</category>

</item>
<item>
    <title>Active record javascript objects using cookies</title>
    <link>http://codeinthehole.com/archives/6-Active-record-javascript-objects-using-cookies.html</link>
            <category>Development</category>
    
    <comments>http://codeinthehole.com/archives/6-Active-record-javascript-objects-using-cookies.html#comments</comments>
    <wfw:comment>http://codeinthehole.com/wfwcomment.php?cid=6</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://codeinthehole.com/rss.php?version=2.0&amp;type=comments&amp;cid=6</wfw:commentRss>
    

    <author>nospam@example.com (David Winterbottom)</author>
    <content:encoded>
    &lt;p&gt;Building on &lt;a href=&quot;http://codeinthehole.com/archives/5-Javascript-cookie-objects-using-Prototype-and-JSON.html&quot; title=&quot;Read previous post on javascript cookie objects&quot;&gt;a previous post on javascript cookie objects&lt;/a&gt;, it is possible to create a simple &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/martinfowler.com/eaaCatalog/layerSupertype.html&#039;);&quot;  href=&quot;http://martinfowler.com/eaaCatalog/layerSupertype.html&quot; title=&quot;A pattern from Martin Fowler&#039;s excellent book&quot;&gt;layer supertype&lt;/a&gt; object that persists objects between requests.   This works by defining an &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/en.wikipedia.org/wiki/Active_record_pattern&#039;);&quot;  href=&quot;http://en.wikipedia.org/wiki/Active_record_pattern&quot; title=&quot;Active record definition at Wikipedia&quot;&gt;active-record&lt;/a&gt;-like interface for saving an object&#039;s properties to a JSON-encoded cookie.  Objects can then be reloaded on later requests and will have all their properties populated automatically.&lt;/p&gt;
&lt;p&gt;
Such behaviour can be useful in javascript-heavy applications, where complex javascript objects are used that don&#039;t map easily back to server-side data.  In these instance, it is much easier to persist these objects on the client-side.  
&lt;/p&gt;

&lt;p&gt;
Once more, this extension relies on the &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.prototypejs.org&#039;);&quot;  href=&quot;http://www.prototypejs.org&quot;&gt;Prototype javascript library&lt;/a&gt; to provide the mechanisms for class definition and inheritance.
&lt;/p&gt;
&lt;p&gt;The layer supertype is defined as follows:
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; PersistentObject = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;Class&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; id: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;null&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Create object and attempt to load properties from cookie&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; initialize: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;store&lt;/span&gt; = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; JsonCookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;id&lt;/span&gt; = id;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;load&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Loads properties if they can be found from store&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; load: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; savedProperties = &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;store&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;savedProperties&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; $H&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;savedProperties&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;pair&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;pair.&lt;span style=&quot;color: #006600;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = pair.&lt;span style=&quot;color: #006600;&quot;&gt;value&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Saves properties encoded as JSON string in cookie&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; save: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; properties = &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; $H&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;pair&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;typeof&lt;/span&gt; pair.&lt;span style=&quot;color: #006600;&quot;&gt;key&lt;/span&gt; != &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;function&#039;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;id&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;store&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;indexOf&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;pair.&lt;span style=&quot;color: #006600;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; == -&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; properties&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;pair.&lt;span style=&quot;color: #006600;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = pair.&lt;span style=&quot;color: #006600;&quot;&gt;value&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;store&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;id&lt;/span&gt;, properties&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&amp;#160; &amp;#160; &lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Deletes data from cookie storage&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;delete&lt;/span&gt;: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;store&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
There&#039;s nothing difficult here: this object composes an instance of the JsonCookies object and then persists the object properties in a JSON-encoded cookie when the save() method is called.  On later instantiations, the object checks for a matching cookie and, if one exists, reloads the properties.&lt;/p&gt;
&lt;p&gt;The only subtlety is to carefully choose an immutable id to identify the object.  Of course, in the absence of auto-incrementing database fields to provide (meaningless) object ids, one would have to choose another suitable identifier which was immutable with respect to the object in question.&lt;/p&gt;
&lt;p&gt;
Basic usage would then involve defining simple subclasses:&lt;/p&gt;
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; Person = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;Class&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;PersistentObject, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt;: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;null&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; initialize: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;$super, id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; $super&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;person_&#039;&lt;/span&gt;+id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; sayName: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160;&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;My name is &#039;&lt;/span&gt;+&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Instances of this person object can then be manipulated as follows:&lt;/p&gt;
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; me = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; Person&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// 1 is the immutable id for this person&lt;/span&gt;&lt;br /&gt;me.&lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt; = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;David&#039;&lt;/span&gt;;&lt;br /&gt;me.&lt;span style=&quot;color: #006600;&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// This writes the name data to a JSON-encoded cookie identified by person_1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// In later request, reload object&lt;/span&gt;&lt;br /&gt;me = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; Person&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;me.&lt;span style=&quot;color: #006600;&quot;&gt;sayName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// And later on - best to clean up as cookie storage is limited&lt;/span&gt;&lt;br /&gt;me = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; Person&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;me.&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;A &lt;a href=&quot;http://codeinthehole.com/app/js/tp/jsunit/testRunner.html?testPage=/app/js/tests/test_persistentobject.html&quot;&gt;working set of unit-tests can be run&lt;/a&gt; that tests the above object using a simple stub - these use the &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.jsunit.net/&#039;);&quot;  href=&quot;http://www.jsunit.net/&quot;&gt;JSUnit&lt;/a&gt; test suite.&lt;/p&gt;

&lt;h4&gt;Health warning&lt;/h4&gt;
&lt;p&gt;It should be noted that there are several shortcomings with using cookies for data persistence in this way  To start with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cookie storage is limited to around 4kb and around 20 key-value pairs per domain.  This covers &lt;em&gt;all&lt;/em&gt; cookies including google analytics and other gubbins.&lt;/li&gt;
&lt;li&gt;Cookies are transmitted over HTTP for every request.  Having several JSON-encoded object strings in the header of every request is a rather unnecessary overhead.&lt;/li&gt;
&lt;li&gt;Cookies are stored on the client&#039;s machine and are thus susceptible to tampering or snooping.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For these reasons, it is always a good idea to delete object cookies as soon as they are finished with.&lt;/p&gt;
&lt;p&gt;Even with these limitations, persisting objects on the client-side is still a useful option - to be used carefully of course.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download &lt;a href=&quot;http://codeinthehole.com/app/js/cookie.js&quot;&gt;cookie.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download &lt;a href=&quot;http://codeinthehole.com/app/js/persistentobject.js&quot;&gt;persistentobject.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download &lt;a href=&quot;http://codeinthehole.com/app/js/persistentobject-and-cookie.js&quot;&gt;persistentobject-and-cookie.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; the source code for this persistent object is now available through the Prototype extensions site &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/scripteka.com/&#039;);&quot;  href=&quot;http://scripteka.com/&quot; title=&quot;Scripteka&quot;&gt;Scripteka&lt;/a&gt;.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 08 Nov 2008 18:29:01 +0000</pubDate>
    <guid isPermaLink="false">http://codeinthehole.com/archives/6-guid.html</guid>
    <category>design patterns</category>
<category>javascript</category>

</item>
<item>
    <title>Javascript cookie objects using Prototype and JSON</title>
    <link>http://codeinthehole.com/archives/5-Javascript-cookie-objects-using-Prototype-and-JSON.html</link>
            <category>Development</category>
    
    <comments>http://codeinthehole.com/archives/5-Javascript-cookie-objects-using-Prototype-and-JSON.html#comments</comments>
    <wfw:comment>http://codeinthehole.com/wfwcomment.php?cid=5</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://codeinthehole.com/rss.php?version=2.0&amp;type=comments&amp;cid=5</wfw:commentRss>
    

    <author>nospam@example.com (David Winterbottom)</author>
    <content:encoded>
    &lt;p&gt;
It&#039;s sometime useful to interact with cookies directly on the client-side using javascript.  This can be useful for a variety of situations, such as persisting display settings between page requests without storing anything on the server.  I&#039;ve also used them to display a simple welcome message to new visitors.  It can make your controller code simpler if this kind of simple display logic is contained entirely on the client side.&lt;/p&gt;
&lt;p&gt;
To this end, I use the following simple Cookies object, build on top of the &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.prototypejs.org&#039;);&quot;  href=&quot;http://www.prototypejs.org&quot;&gt;Prototype Javascript library&lt;/a&gt; (version &gt; 1.5):&lt;/p&gt;
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; Cookies = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;Class&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; initialize: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;path, domain&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;path&lt;/span&gt; = path || &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;/&#039;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;domain&lt;/span&gt; = domain || &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Sets a cookie&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; set: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key, value, days&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;typeof&lt;/span&gt; key != &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;string&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&quot;Invalid key&quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;typeof&lt;/span&gt; value != &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;string&#039;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;typeof&lt;/span&gt; value != &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;number&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&quot;Invalid value&quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;days &amp;amp;&amp;amp; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;typeof&lt;/span&gt; days != &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;number&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&quot;Invalid expiration time&quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; setValue = key+&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;=&#039;&lt;/span&gt;+escape&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; String&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;value&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;days&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; date = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; Date&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; date.&lt;span style=&quot;color: #006600;&quot;&gt;setTime&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;date.&lt;span style=&quot;color: #006600;&quot;&gt;getTime&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;+&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;days*&lt;span style=&quot;color: #CC0000;&quot;&gt;24&lt;/span&gt;*&lt;span style=&quot;color: #CC0000;&quot;&gt;60&lt;/span&gt;*&lt;span style=&quot;color: #CC0000;&quot;&gt;60&lt;/span&gt;*&lt;span style=&quot;color: #CC0000;&quot;&gt;1000&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; setExpiration = &lt;span style=&quot;color: #3366CC;&quot;&gt;&quot;; expires=&quot;&lt;/span&gt;+date.&lt;span style=&quot;color: #006600;&quot;&gt;toGMTString&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; setExpiration = &lt;span style=&quot;color: #3366CC;&quot;&gt;&quot;&quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; setPath = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;; path=&#039;&lt;/span&gt;+escape&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; setDomain = &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;domain&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ? &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;; domain=&#039;&lt;/span&gt;+escape&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;domain&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; : &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;&#039;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; cookieString = setValue+setExpiration+setPath+setDomain;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; document.&lt;span style=&quot;color: #006600;&quot;&gt;cookie&lt;/span&gt; = cookieString;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Returns a cookie value or false&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; get: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; keyEquals = key+&lt;span style=&quot;color: #3366CC;&quot;&gt;&quot;=&quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; value = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; document.&lt;span style=&quot;color: #006600;&quot;&gt;cookie&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;;&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;invoke&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;strip&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;s&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;s.&lt;span style=&quot;color: #006600;&quot;&gt;startsWith&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;keyEquals&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; value = unescape&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;s.&lt;span style=&quot;color: #006600;&quot;&gt;substring&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;keyEquals.&lt;span style=&quot;color: #006600;&quot;&gt;length&lt;/span&gt;, s.&lt;span style=&quot;color: #006600;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;throw&lt;/span&gt; $break;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;return&lt;/span&gt; value;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Clears a cookie&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; clear: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key,&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;&#039;&lt;/span&gt;,-&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Clears all cookies&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; clearAll: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; document.&lt;span style=&quot;color: #006600;&quot;&gt;cookie&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;;&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;collect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;s&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;return&lt;/span&gt; s.&lt;span style=&quot;color: #006600;&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;=&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;strip&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
The API is simple: cookie objects are created with optional path and domain arguments to the constructor.  The set(), get() and clear() methods are then used to define the name=value pairs that cookies comprise.  In addition, the get() method takes an optional third parameter for setting the expiry time in days if you want the data persisted longer than the current session.
&lt;/p&gt;
&lt;p&gt;
Cookies can now be interacted with in the following manner:
&lt;/p&gt;
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; biscuits = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; Cookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;biscuits.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;show_nav&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;yes&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;biscuits.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;show_nav&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Show the navigation...&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
The above object is useful for storing simple string data, but we can easily extend the above to allow arrays and objects to be persisted in the cookie by using JSON.
&lt;/p&gt;
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; JsonCookies = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;Class&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;Cookies, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;JsonCookies.&lt;span style=&quot;color: #006600;&quot;&gt;addMethods&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Overridden set method to JSON-encode value&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; set: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;$super, key, value, days&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;switch&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;typeof&lt;/span&gt; value&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;undefined&#039;&lt;/span&gt;:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;function&#039;&lt;/span&gt;:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;unknown&#039;&lt;/span&gt;: &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&quot;Invalid value type&quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;boolean&#039;&lt;/span&gt;: &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;string&#039;&lt;/span&gt;: &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;number&#039;&lt;/span&gt;: &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; value = String&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;value.&lt;span style=&quot;color: #006600;&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; $super&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key, Object.&lt;span style=&quot;color: #006600;&quot;&gt;toJSON&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;value&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, days&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Overriden get method to JSON-decode the value&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; get: &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;$super, key&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; value = $super&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;key&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;value&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ? value.&lt;span style=&quot;color: #006600;&quot;&gt;evalJSON&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; : &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
As we&#039;re overriding the set and get methods, the API remains the same:
&lt;/p&gt;
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Persist some array data&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; hobnobs = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; JsonCookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;hobnobs.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;selectedIds&#039;&lt;/span&gt;, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;12&lt;/span&gt;,&lt;span style=&quot;color: #CC0000;&quot;&gt;46&lt;/span&gt;,&lt;span style=&quot;color: #CC0000;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;, &lt;span style=&quot;color: #CC0000;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// On a different request, use the data&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; hobnobs = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; JsonCookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; selectedIds = hobnobs.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;selectedIds&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #000066; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;selectedIds&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160;&lt;span style=&quot;color: #009900; font-style: italic;&quot;&gt;// Do something with the selected ids&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
As this object does not rely on the DOM in any way, it is easily testable as it requires little in the way of fixtures.  What follows is set of unit tests that work with the &lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.jsunit.net/&#039;);&quot;  href=&quot;http://www.jsunit.net/&quot; title=&quot;JSUnit&quot;&gt;JSUnit testing suite&lt;/a&gt;.  
You can &lt;a href=&quot;http://codeinthehole.com/app/js/tp/jsunit/testRunner.html?testPage=http://codeinthehole.com/app/js/tests/test_cookie.html&quot;&gt;run the unit tests&lt;/a&gt; directly, using the JSUnit test runner.
&lt;/p&gt;
&lt;div class=&quot;javascript&quot; style=&quot;text-align: left&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; myKey&amp;#160; &amp;#160; = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;hereismykey&#039;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; myValue&amp;#160; = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;hereismyvalue&#039;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; myCookies;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt; setUp&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; myCookies = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; Cookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;myKey, myValue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt; testSet&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; cookieString = myKey+&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;=&#039;&lt;/span&gt;+myValue;&lt;br /&gt;&amp;#160; &amp;#160; assertTrue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Cookies set&#039;&lt;/span&gt;, document.&lt;span style=&quot;color: #006600;&quot;&gt;cookie&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;indexOf&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;cookieString&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; != -&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt; testGet&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; assertEquals&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Cookies get&#039;&lt;/span&gt;, myValue, myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;myKey&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt; testClear&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;myKey&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; assertFalse&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Cookies clear&#039;&lt;/span&gt;, myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;myKey&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt; testClearAll&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; myNewKey&amp;#160; &amp;#160;= &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;hereismynewkey&#039;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; myNewValue = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;hereismynewvalue&#039;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;myNewKey, myNewValue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;clearAll&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; assertFalse&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Check cookie has been cleared for myKey&#039;&lt;/span&gt;, myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;myKey&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; assertFalse&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Check cookie has been cleared for myNewKey&#039;&lt;/span&gt;, myCookies.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;myNewValue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt; testArrayInJsonCookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; testKey&amp;#160; &amp;#160;= &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;test&#039;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; testValue = &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;,&lt;span style=&quot;color: #CC0000;&quot;&gt;2&lt;/span&gt;,&lt;span style=&quot;color: #CC0000;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; jar = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; JsonCookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; jar.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testKey, testValue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; testReturn = jar.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testKey&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; assertTrue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Check length of array is the same&#039;&lt;/span&gt;, testValue.&lt;span style=&quot;color: #006600;&quot;&gt;length&lt;/span&gt; == testReturn.&lt;span style=&quot;color: #006600;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; assertEquals&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Checking arrays are the same&#039;&lt;/span&gt;, $A&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testValue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;toJSON&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, $A&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testReturn&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;toJSON&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt; testObjectInJsonCookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; testKey&amp;#160; &amp;#160;= &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;test&#039;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; testValue = &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;name&#039;&lt;/span&gt;:&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;barry&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;age&#039;&lt;/span&gt;: &lt;span style=&quot;color: #CC0000;&quot;&gt;29&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; jar = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;new&lt;/span&gt; JsonCookies&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; jar.&lt;span style=&quot;color: #006600;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testKey, testValue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; testReturn = jar.&lt;span style=&quot;color: #006600;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testKey&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; assertTrue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Check length of array is the same&#039;&lt;/span&gt;, testValue.&lt;span style=&quot;color: #006600;&quot;&gt;length&lt;/span&gt; == testReturn.&lt;span style=&quot;color: #006600;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;#160; &amp;#160; assertEquals&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;Checking objects are the same&#039;&lt;/span&gt;, $A&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testValue&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;toJSON&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, $A&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;testReturn&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #006600;&quot;&gt;toJSON&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
One minor shortcoming of the present version of JSUnit is that it is difficult to test equality of arrays and objects.  The simple work-around used above is to test equality of their JSON encodings, which acheives the same end without resorting to looping through comparing property by property.
&lt;/p&gt;
&lt;p&gt;
It should be noted that I am far from the first person to create Javascript cookie objects in this way - here are a few others doing similar things:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.phpied.com/json-javascript-cookies/&#039;);&quot;  href=&quot;http://www.phpied.com/json-javascript-cookies/&quot;&gt;JSON javascript cookies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a onclick=&quot;javascript: pageTracker._trackPageview(&#039;/extlink/www.lalit.org/lab/jsoncookies&#039;);&quot;  href=&quot;http://www.lalit.org/lab/jsoncookies&quot;&gt;Cookie Jar: Yummy JSON encoded cookies with Prototype&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The main difference is that my objects use an inheritance structure to add the JSON-encoding facilities and throw errors when invalid arguments are passed.  Also, I have another post in the pipeline which builds on these cookie objects to do something cool.  Watch this space.
&lt;/p&gt;

 
    </content:encoded>

    <pubDate>Fri, 07 Nov 2008 17:00:24 +0000</pubDate>
    <guid isPermaLink="false">http://codeinthehole.com/archives/5-guid.html</guid>
    <category>javascript</category>
<category>json</category>
<category>jsunit</category>

</item>

</channel>
</rss>