<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Codeology</title>
	<atom:link href="http://codeology.lloydkinsella.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://codeology.lloydkinsella.net</link>
	<description>The coding horrors of Lloyd Kinsella.</description>
	<pubDate>Mon, 07 Jun 2010 12:24:41 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Litmos API</title>
		<link>http://codeology.lloydkinsella.net/?p=215</link>
		<comments>http://codeology.lloydkinsella.net/?p=215#comments</comments>
		<pubDate>Mon, 07 Jun 2010 12:24:41 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[ExtJS]]></category>

		<category><![CDATA[LMS]]></category>

		<category><![CDATA[Litmos]]></category>

		<category><![CDATA[REST]]></category>

		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=215</guid>
		<description><![CDATA[I spent the weekend working on writing a better API wrapper for Litmos, if you don&#8217;t know what Litmos is it&#8217;s a Learning Management System; it&#8217;s quite simple and uses ExtJS in some parts and has a nice REST API for management which is the part I&#8217;ve been wrapping.
Litmos itself provides a .NET 3 WCF [...]]]></description>
			<content:encoded><![CDATA[<p>I spent the weekend working on writing a better API wrapper for <a href="http://www.litmos.com/">Litmos</a>, if you don&#8217;t know what Litmos is it&#8217;s a <a href="http://en.wikipedia.org/wiki/Learning_management_system">Learning Management System</a>; it&#8217;s quite simple and uses ExtJS in some parts and has a nice REST API for management which is the part I&#8217;ve been wrapping.</p>
<p>Litmos itself provides a .NET 3 WCF service however it&#8217;s limited and requires you to know/understand the underlying REST calls. I removed these requirements and wrote it as an object orientated framework for .NET 2.0. Currently it&#8217;s only available as a repository checkout from Google Code but I&#8217;m working on a proper binary release.</p>
<p>Check out the project space <a href="http://code.google.com/p/sharplitmos/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=215</wfw:commentRss>
		</item>
		<item>
		<title>Articles in JSMag!</title>
		<link>http://codeology.lloydkinsella.net/?p=211</link>
		<comments>http://codeology.lloydkinsella.net/?p=211#comments</comments>
		<pubDate>Wed, 12 May 2010 14:47:14 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[Caching]]></category>

		<category><![CDATA[ExtJS]]></category>

		<category><![CDATA[HTTP]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=211</guid>
		<description><![CDATA[Just to announce although a bit late for April, but I&#8217;ve recently wrote two articles for JSMag. I highly recommend JSMag to any JavaScript developers who may be reading this.
My first article in April details with using on-demand JavaScript loaded with ExtJS - http://www.jsmag.com/main.issues.description/id=31/
The second article, for May details implementing client-side caching of JavaScript - [...]]]></description>
			<content:encoded><![CDATA[<p>Just to announce although a bit late for April, but I&#8217;ve recently wrote two articles for JSMag. I highly recommend JSMag to any JavaScript developers who may be reading this.</p>
<p>My first article in April details with using on-demand JavaScript loaded with ExtJS - <a href="http://www.jsmag.com/main.issues.description/id=31/">http://www.jsmag.com/main.issues.description/id=31/</a></p>
<p>The second article, for May details implementing client-side caching of JavaScript - <a href="http://www.jsmag.com/main.issues.description/id=32/">http://www.jsmag.com/main.issues.description/id=32/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=211</wfw:commentRss>
		</item>
		<item>
		<title>ExtJS Cache Class</title>
		<link>http://codeology.lloydkinsella.net/?p=206</link>
		<comments>http://codeology.lloydkinsella.net/?p=206#comments</comments>
		<pubDate>Tue, 09 Feb 2010 00:21:36 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[Caching]]></category>

		<category><![CDATA[ExtJS]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=206</guid>
		<description><![CDATA[I had some spare time this evening so I started to play around and wrote my own client side JavaScript object cache for use with ExtJS. It&#8217;s fairly simple to use with get/set functions to call and works in terms of seconds, for example to cache a simple JavaScript object you can do:

Ext.ux.Cache.set("myJsonData",{test: 1234},10);

This would [...]]]></description>
			<content:encoded><![CDATA[<p>I had some spare time this evening so I started to play around and wrote my own client side JavaScript object cache for use with ExtJS. It&#8217;s fairly simple to use with get/set functions to call and works in terms of seconds, for example to cache a simple JavaScript object you can do:</p>
<pre name="code" class="brush: js;">
Ext.ux.Cache.set("myJsonData",{test: 1234},10);
</pre>
<p>This would cache it for ten seconds before having it removed. I&#8217;ve even implemented some events. To be notified when items expire for example:</p>
<pre name="code" class="brush: js;">
Ext.ux.Cache.on("expired",function(cache,removed) {
  alert(removed.length + " items expired.");
});
</pre>
<p>This comes into its own with the likes of AJAX requests, one test scenario:</p>
<pre name="code" class="brush: js;">
function dataSuccess(data) {
    ...
};

if (Ext.ux.Cache.has("data")) {
    // Process cached data
    dataSuccess(Ext.ux.Cache.get("data"));
} else {
    // Request new data
    Ext.Ajax.request({
        url: "whatever.ashx",
        scope: this,
        success: function(response,options) {
            // Decode data
            var data = Ext.decode(response.responseText);

            // Cache data for 30 seconds
            Ext.ux.Cache.set("data",data,30);

            // Process data
            dataSuccess(data);
        }
    });
}
</pre>
<p>Anyhow enough of the examples here&#8217;s the actual code for you to play with:</p>
<pre name="code" class="brush: js;">
Ext.ux.CacheEngine = Ext.extend(Ext.util.Observable,{

    cache: [],

    constructor: function(config) {

        this.addEvents({
            "added": true,
            "updated": true,
            "removed": true,
            "expired": true
        });

        Ext.apply(this,config);

        var cache_task = {
            run: function() {
                // Get current time
                var now = new Date().getTime();

                // Process cache items to remove
                var to_remove = [];

                for(var i = 0, len = this.cache.length; i < len; i++) {
                    // Get cached item
                    var item = this.cache[i];

                    // Check time
                    if (item.expires < now) to_remove.push(item);
                }

                // Remove items
                var removed = [];

                for(var i = 0, len = to_remove.length; i < len; i++) {
                    var item = to_remove[i];
                    var removed_item = {
                        key: item.key,
                        value: item.value
                    };

                    removed.push(removed_item);
                    this.cache.remove(item);
                }

                // Fire event
                if (removed.length > 0) this.fireEvent("expired",this,removed);
            },
            interval: 1000,
            scope: this
        };

        Ext.TaskMgr.start(cache_task);

        // Call our superclass constructor to complete construction process.
        Ext.ux.CacheEngine.superclass.constructor.call(config)
    },

    clear: function()
    {
        this.cache = [];
    },

    get: function(key)
    {
        // Get item
        for(var i = 0, len = this.cache.length; i < len; i++) {
            var item = this.cache[i];

            if (key == item.key) return item.value;
        }

        // Return
        return null;
    },

    set: function(key,value,timeout)
    {
        timeout = timeout || 10;

        // Find item
        for(var i = 0, len = this.cache.length; i < len; i++) {
            var item = this.cache[i];

            if (key == item.key) {
                // Update item
                item.value = value;
                item.expires = new Date().getTime() + (timeout * 1000);

                // Fire event
                this.fireEvent("updated",this);

                // Return
                return;
            }
        }

        // Add new item
        var item = {
            key: key,
            value: value,
            expires: new Date().getTime() + (timeout * 1000)
        };
        this.cache.push(item);

        // Fire event
        this.fireEvent("added",this);
    },

    remove: function(key)
    {
        // Find item
        for(var i = 0, len = this.cache.length; i < len; i++) {
            var item = this.cache[i];

            if (key == item.key) {
                // Remove item
                this.cache.remove(item);

                // Fire event
                this.fireEvent("removed",this);

                // Return
                return true;
            }
        }

        // Return
        return false;
    },

    has: function(key)
    {
        // Look for key
        for(var i = 0, len = this.cache.length; i < len; i++) {
            // Get item
            var item = this.cache[i];

            // Compare keys
            if (key == item.key) return true;
        }

        // Return
        return false;
    }

});

Ext.ux.Cache = new Ext.ux.CacheEngine();
</pre>
<p>I&#8217;m going to attempt to create a cached DataProxy and DataReader at some point, that should provide a more useful feature for ExtJS users so they can plug it in directly into existing code.</p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=206</wfw:commentRss>
		</item>
		<item>
		<title>Fun with ExtJS and Adobe AIR</title>
		<link>http://codeology.lloydkinsella.net/?p=198</link>
		<comments>http://codeology.lloydkinsella.net/?p=198#comments</comments>
		<pubDate>Sat, 06 Feb 2010 03:06:26 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[AIR]]></category>

		<category><![CDATA[Adobe]]></category>

		<category><![CDATA[ExtJS]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=198</guid>
		<description><![CDATA[Bored this evening I decided to tinker with Aptana Studio as it has a nice plugin to create Adobe AIR applications. Using this I combined it with ExtJS to produce an AIR application of the documentation which saves you having to use the temperamental ExtJS servers (at the moment) or browse locally, and is also [...]]]></description>
			<content:encoded><![CDATA[<p>Bored this evening I decided to tinker with Aptana Studio as it has a nice plugin to create Adobe AIR applications. Using this I combined it with ExtJS to produce an AIR application of the documentation which saves you having to use the temperamental ExtJS servers (at the moment) or browse locally, and is also very snappy. The build I&#8217;ve done is for ExtJS 3.1 though I might fiddle and see if I can get one for 2.x and one for core going later.</p>
<p><center><br />
<a href="http://bimg.lloydkinsella.net/codeology/198/docsair.png" rel="lightbox[198]"><img src="http://bimg.lloydkinsella.net/codeology/198/docsair_thumb.png" border="0" /></a><br />
</center></p>
<p>You can download the AIR application <a href="http://codeology.lloydkinsella.net/downloads/ext-3.1-docs.air">here</a>.<br />
If the above link does not work, try <a href="http://codeology.lloydkinsella.net/downloads/ext-3.1-docs.zip">this one</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=198</wfw:commentRss>
		</item>
		<item>
		<title>A Better ExtJS MessageBox</title>
		<link>http://codeology.lloydkinsella.net/?p=192</link>
		<comments>http://codeology.lloydkinsella.net/?p=192#comments</comments>
		<pubDate>Mon, 30 Nov 2009 11:04:13 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[ExtJS]]></category>

		<category><![CDATA[HTML]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=192</guid>
		<description><![CDATA[I haven&#8217;t posted in quite a while so I thought I&#8217;d pass up a quick alteration to the standard Ext.MessageBox.
Now the original Ext.MessageBox works well however a lot of my windows have buttons with images, including the buttons like &#8220;OK&#8221; and &#8220;Cancel&#8221;. In order to keep with the look and feel I decided to add [...]]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t posted in quite a while so I thought I&#8217;d pass up a quick alteration to the standard Ext.MessageBox.</p>
<p>Now the original Ext.MessageBox works well however a lot of my windows have buttons with images, including the buttons like &#8220;OK&#8221; and &#8220;Cancel&#8221;. In order to keep with the look and feel I decided to add this functionality to ExtJS. Why they haven&#8217;t done this already is beyond me, the change was relatively simple.</p>
<p>You will need to patch the Ext.MessageBox code, there is a function called updateButtons you will need to change like so:</p>
<pre name="code" class="brush: js;">
var updateButtons = function(b){
        var width = 0,
            cfg;
        if(!b){
            Ext.each(buttonNames, function(name){
                buttons[name].hide();
            });
            return width;
        }
        dlg.footer.dom.style.display = '';
        Ext.iterate(buttons, function(name, btn){
            cfg = b[name];
            if(cfg){
                btn.show();

                if (Ext.isObject(cfg)) {
                    if (Ext.isString(cfg.icon)) btn.setIconClass(cfg.icon);

                    btn.setText(Ext.isString(cfg.text) ? cfg.text : Ext.MessageBox.buttonText[name]);
                } else {
                    btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
                }

                width += btn.getEl().getWidth() + 15;
            }else{
                btn.hide();
            }
        });
        return width;
    };
</pre>
<p>And that&#8217;s basically it. You can then do this:</p>
<pre name="code" class="brush: js;">
Ext.MessageBox.show({
    ...
    buttons: {
        ok: {
            text: "Whatever",
            icon: "whatever-css-class"
        }
    },
    ...
});
</pre>
<p>To prove it works here is two screenshots of before and after the fix:</p>
<table style="width: 100%;" border="0" cellspacing="4" align="left">
<tbody>
<tr>
<td width="50%" align="center" valign="middle"><a href="http://bimg.lloydkinsella.net/codeology/192/before.png" rel="lightbox[192]"><img src="http://bimg.lloydkinsella.net/codeology/192/before.png" border="0" /></a></td>
<td width="50%" align="center" valign="middle"><a href="http://bimg.lloydkinsella.net/codeology/192/after.png" rel="lightbox[192]"><img src="http://bimg.lloydkinsella.net/codeology/192/after.png" border="0" /></td>
</tr>
<tr>
<td style="text-align: center;" width="50%"><em>Before</em></td>
<td style="text-align: center;" width="50%"><em>After</em></td>
</tr>
</tbody>
</table>
<p><br/><br />
It should be completely backwards compatible, all your original Ext.MessgeBox code will work as originally intended with no modification.</p>
<p>If you don&#8217;t want to patch ExtJS directly I&#8217;ve ripped the Ext.MessageBox code completely and formed a new variant called Ext.ux.MessageBox which you can use instead. You can get the code to this <a href="http://codeology.lloydkinsella.net/downloads/msgbox.js">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=192</wfw:commentRss>
		</item>
		<item>
		<title>A better .NET cache</title>
		<link>http://codeology.lloydkinsella.net/?p=185</link>
		<comments>http://codeology.lloydkinsella.net/?p=185#comments</comments>
		<pubDate>Thu, 08 Oct 2009 21:34:27 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[Caching]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=185</guid>
		<description><![CDATA[I&#8217;ve been working on implementing caching into some of our products to increase efficiency and speed things up, however I came to a sticking point recently in that our products are often deployed to widely different platforms that don&#8217;t all offer the same feature set. This meant that caching on some systems didn&#8217;t work the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on implementing caching into some of our products to increase efficiency and speed things up, however I came to a sticking point recently in that our products are often deployed to widely different platforms that don&#8217;t all offer the same feature set. This meant that caching on some systems didn&#8217;t work the same or at all on others.</p>
<p>Mulling over this today I decided upon a common <i>cache engine</i> that I could plug various <i>cache providers</i> into for available features allowing me to change which caching system to use depending on the platform without having to alter vast amounts of code.</p>
<p>I constructed a <b>Cache</b> class with static methods, a general outline of the class is as follows:</p>
<pre name="code" class="brush: csharp;">
    public class Cache
    {

        public static void Initialize();
        public static void Uninitialize();

        public static bool Use;

        public static void RegisterProvider(ICacheProvider provider);
        public static void UnregisterProvider(ICacheProvider provider);

        public static object Get(string key);

        public static void Set(string key, object value);
        public static void Set(string key, object value, int minutes);
        public static void Set(string key, object value, DateTime dt);
        public static void Set(string key, object value, TimeSpan ts);

        public static void Unset(string key);

        public static bool Exists(string key);
        public static void Clear();

        public static ICacheProvider Default;
        public static ICacheProvider Empty;

    }
</pre>
<p>This provides a common way to access a cache rather than individualised access methods. For each individual cache system you write a class that implements <b>ICacheProvider</b> which interfaces between the <b>Cache</b> class and the underlying caching system.</p>
<p>The <b>ICacheProvider</b> interface looks like this:</p>
<pre name="code" class="brush: csharp;">
    public interface ICacheProvider
    {

        void Initialize();
        void Unitialize();

        object Get(string key);

        void Set(string key, object value);
        void Set(string key, object value, int minutes);
        void Set(string key, object value, DateTime dt);
        void Set(string key, object value, TimeSpan ts);

        void Unset(string key);

        bool Exists(string key);
        void Clear();

        string Name
        {
            get;
        }

    }
</pre>
<p>As an example implementation take ASP.NET, which provides a cache as part of the HttpRuntime class. I can write an <b>ICacheProvider</b> to interface to it, such as:</p>
<pre name="code" class="brush: csharp;">
    public class HttpRuntimeCacheProvider : CacheProvider
    {

        public override void Initialize()
        {
            // Do nothing...
        }

        public override void Unitialize()
        {
            // Do nothing...
        }

        public override object Get(string key)
        {
            return HttpRuntime.Cache.Get(key);
        }

        public override void Set(string key, object value)
        {
            DateTime expires = DateTime.UtcNow.AddMinutes(10);

            Set(key,value,expires);
        }

        public override void Set(string key, object value, DateTime dt)
        {
            DateTime expires = dt.ToUniversalTime();

            HttpRuntime.Cache.Insert(key,value,null,expires,System.Web.Caching.Cache.NoSlidingExpiration);
        }

        public override void Unset(string key)
        {
            HttpRuntime.Cache.Remove(key);
        }

        public override bool Exists(string key)
        {
            object value = Get(key);

            return (value != null);
        }

        public override void Clear()
        {
            List&lt;string&gt; keys = new List&lt;string&gt;();

            foreach(DictionaryEntry entry in HttpRuntime.Cache) keys.Add(entry.Key.ToString());
            foreach(string key in keys) HttpRuntime.Cache.Remove(key);
        }

        public override string Name
        {
            get {
                return "HttpRuntime";
            }
        }

    }
</pre>
<p>We can register and set as default using:</p>
<pre name="code" class="brush: csharp;">
ICacheProvider provider = new HttpRuntimeCacheProvider();

Cache.RegisterProvider(provider);
Cache.Default = provider;
</pre>
<p>All future requests via <b>Cache</b> will now be handled by the ASP.NET cache.</p>
<p>In the included downloadable source code I&#8217;ve wrote providers for ASP.NET, MemCached and my own simple example provider. You can of course take this further and write one to use a database for example.</p>
<p>Below you&#8217;ll find the source code to download. I&#8217;ve used a custom build of a .NET MemCached client which I&#8217;ve also included a link to download. The original can be found <a href="http://code.google.com/p/beitmemcached/">here</a>.</p>
<p>As always comments and suggestions welcome!</p>
<table style="width: 100%;" border="0" cellspacing="4">
<tbody>
<tr>
<td width="48" height="48" align="center" valign="middle"><img src="http://bimg.lloydkinsella.net/codeology/zip-icon.png" border="0"/></td>
<td align="left" valign="middle"><a href="http://codeology.lloydkinsella.net/downloads/caching_engine.zip">caching_engine.zip</a><br/>30 KB</td>
</tr>
</tbody>
</table>
<table style="width: 100%;" border="0" cellspacing="4">
<tbody>
<tr>
<td width="48" height="48" align="center" valign="middle"><img src="http://bimg.lloydkinsella.net/codeology/zip-icon.png" border="0"/></td>
<td align="left" valign="middle"><a href="http://codeology.lloydkinsella.net/downloads/beit_memcached.zip">beit_memcached.zip</a><br/>104 KB</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=185</wfw:commentRss>
		</item>
		<item>
		<title>A JavaScript StringBuilder</title>
		<link>http://codeology.lloydkinsella.net/?p=176</link>
		<comments>http://codeology.lloydkinsella.net/?p=176#comments</comments>
		<pubDate>Thu, 30 Jul 2009 14:25:56 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[ExtJS]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=176</guid>
		<description><![CDATA[One of the things I like in .NET is the StringBuilder class and since like .NET, JavaScript strings are immutable it makes sense to have one for JavaScript too. I&#8217;ve wrote a simple approximation that uses Array and Array.join().
I&#8217;ve built this version for use with Ext however you can easily adapt it to run outside [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I like in .NET is the StringBuilder class and since like .NET, JavaScript strings are immutable it makes sense to have one for JavaScript too. I&#8217;ve wrote a simple approximation that uses Array and Array.join().</p>
<p>I&#8217;ve built this version for use with Ext however you can easily adapt it to run outside of Ext:</p>
<pre name="code" class="brush: js;">
Ext.namespace("Ext.util");

Ext.util.StringBuilder = function()
{

    var buffer = [];
    var length = 0;

    this.getLength = function()
    {
        return length;
    };

    this.clear = function()
    {
        buffer = [];
        length = 0;
    };

    this.append = function(s)
    {
        if (s == null) return;

        length += s.length;
        buffer.push(s);
    };

    this.appendLine = function(s)
    {
        if (s == null) return;

        var _s = s + "\r\n";

        length += _s.length;
        buffer.push(_s);
    };

    this.toString = function()
    {
        return buffer.join("");
    };

}
</pre>
<p>You can use it like this:</p>
<pre name="code" class="brush: js;">
var sb = new Ext.util.StringBuilder();

sb.append("Hello");
sb.append(" ");
sb.append("World");

var s = sb.toString();

alert(s);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=176</wfw:commentRss>
		</item>
		<item>
		<title>Enhancing Ext.tree.TreeLoader</title>
		<link>http://codeology.lloydkinsella.net/?p=173</link>
		<comments>http://codeology.lloydkinsella.net/?p=173#comments</comments>
		<pubDate>Tue, 21 Jul 2009 16:29:12 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ExtJS]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=173</guid>
		<description><![CDATA[One of my annoyances with Ext is sometimes some of the widgets only half do what you want and only half support features you&#8217;d expect.
Take the TreeLoader, responsible for loading nodes into a Tree. It works well most of the time and I don&#8217;t usually need to complain about it, until today. I needed to [...]]]></description>
			<content:encoded><![CDATA[<p>One of my annoyances with Ext is sometimes some of the widgets only half do what you want and only half support features you&#8217;d expect.</p>
<p>Take the TreeLoader, responsible for loading nodes into a Tree. It works well most of the time and I don&#8217;t usually need to complain about it, until today. I needed to increase the time-out for the request only the TreeLoader exposes just two configuration options for the actual request, a requestMethod so you can switch between GET and POST and the actual url. Reading the documentation and looking through Firebug there seemed no way of doing what I wanted so I had to delve into the actual source code.</p>
<p>It turns out yet again I need to override a core function of the component, requestData and alter the AJAX request myself. Rather than do a complete override which would affect ALL TreeLoader&#8217;s I instead extended it, the full code can be seen below:</p>
<pre name="code" class="brush: js;">
    DCStorm.IQ.Profiles.TreeLoader = Ext.extend(Ext.tree.TreeLoader,
    {

        requestData : function(node, callback, scope){
            if(this.fireEvent("beforeload", this, node, callback) !== false){
                if(this.directFn){
                    var args = this.getParams(node);
                    args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
                    this.directFn.apply(window, args);
                }else{
                    this.transId = Ext.Ajax.request({
                        method:this.requestMethod,
                        url: this.dataUrl || this.url,
                        timeout: this.requestTimeout,
                        success: this.handleResponse,
                        failure: this.handleFailure,
                        scope: this,
                        argument: {callback: callback, node: node, scope: scope},
                        params: this.getParams(node)
                    });
                }
            }else{
                // if the load is cancelled, make sure we notify
                // the node that we are done
                this.runCallback(callback, scope || node, []);
            }
        }

    });
</pre>
<p>The only part I actually modified was the AJAX request, I simply added a timeout configuration option and had it pull the requestTimeout value, as can be seen on line 14. So in my new TreeLoader I can do this (line 5):</p>
<pre name="code" class="brush: js;">
        loader: new DCStorm.IQ.Profiles.TreeLoader({
             preloadChildren: true,
             clearOnLoad: true,
             requestMethod: "POST",
             requestTimeout: (60 * 2) * 1000,
             dataUrl: "profiles/backend/profiles.ashx?action=columnstree",
             baseParams: {
                        //action: "columnstree",
                        view: this.viewName,
                        level: this.profile.profile.level,
                        agency: ((this.profile.profile.level == 1) ? this.profile.profile.agency : 0),
                        site: ((this.profile.profile.level == 2) ? this.profile.profile.site : 0),
                        sitegroup: ((this.profile.profile.level == 1) ? this.profile.profile.sitegroup : 0),
                        type: "groupings",
                        filter: "",
                        selected: ""
             }
       }),
</pre>
<p>And that&#8217;s pretty much it.</p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=173</wfw:commentRss>
		</item>
		<item>
		<title>Quick ASP.NET Caching</title>
		<link>http://codeology.lloydkinsella.net/?p=165</link>
		<comments>http://codeology.lloydkinsella.net/?p=165#comments</comments>
		<pubDate>Fri, 17 Jul 2009 15:46:09 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=165</guid>
		<description><![CDATA[One thing we&#8217;ve often found useful but underused is response caching, especially in the Web 2.0 world. There are a variety of options available and here&#8217;s a quick example of how to use the built in caching in ASP.NET.
For our example we&#8217;re going to cache for no more than 10 minutes, you can alter this [...]]]></description>
			<content:encoded><![CDATA[<p>One thing we&#8217;ve often found useful but underused is response caching, especially in the Web 2.0 world. There are a variety of options available and here&#8217;s a quick example of how to use the built in caching in ASP.NET.</p>
<p>For our example we&#8217;re going to cache for no more than 10 minutes, you can alter this as suits you. We&#8217;re also caching on an absolute time-scale but ASP.NET lets you also set a sliding time-scale.</p>
<pre name="code" class="brush: csharp;">
public void ProcessRequest(HttpContext context)
{
        // Set Content Type
        context.Response.ContentType = "application/json";

        // Set key
        string key = "mydata";

        // Check cache for our hash
        object cache = context.Cache.Get(key);

        if (cache != null) {
            // Write out cached item
            context.Response.Write("/* From Cache */\r\n");
            context.Response.Write(cache.ToString());
            context.Response.Flush();

            // Return
            return;
        }

        // Get JSON from database or wherever
        string json = "{test:'Hello'}";

        context.Response.Write(json);
        context.Response.Flush();

        // Add response to cache
        context.Cache.Insert(
            key,
            json,
            null,
            DateTime.UtcNow.AddMinutes(10),
            System.Web.Caching.Cache.NoSlidingExpiration
        );
}
</pre>
<p>What happens is on the request we first check the cache for <i>key</i>. If we find that the cached item exists we retrieve this from the cache and dump that into the response.</p>
<p>If the item doesn&#8217;t exist however we generate the item content, be it a database call or whatever. Here this is mostly some kind of JSON so once we have the content we&#8217;d normally return we again dump that into the response but this time we also add it to the cache with the same <i>key</i>.</p>
<p>Caching is great for reducing load on databases and processing time, especially with commonly returned data such as dropdown lists who&#8217;s data rarely changes.</p>
<p>For further reading and a more fuller introduction to ASP.NET caching <a href="http://msdn.microsoft.com/en-us/library/xsbfdd8c(VS.71).aspx">click here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=165</wfw:commentRss>
		</item>
		<item>
		<title>What the fuck is OxyFuck?</title>
		<link>http://codeology.lloydkinsella.net/?p=159</link>
		<comments>http://codeology.lloydkinsella.net/?p=159#comments</comments>
		<pubDate>Fri, 27 Mar 2009 17:13:18 +0000</pubDate>
		<dc:creator>Lloyd</dc:creator>
		
		<category><![CDATA[BrainFuck]]></category>

		<category><![CDATA[Interpreters]]></category>

		<category><![CDATA[Languages]]></category>

		<category><![CDATA[Oxygene]]></category>

		<category><![CDATA[Prism]]></category>

		<category><![CDATA[RemObjects]]></category>

		<category><![CDATA[Tokenizers]]></category>

		<guid isPermaLink="false">http://codeology.lloydkinsella.net/?p=159</guid>
		<description><![CDATA[I was bored this afternoon so spent some time playing around writing an interpreter in .NET for BrainFuck. It works for the most part though I have had it do odd stuff but I&#8217;m not sure why, I&#8217;ll revisit it later perhaps. You can download the code here.It&#8217;s in RemObjects Oxygene but as normal I&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>I was bored this afternoon so spent some time playing around writing an interpreter in .NET for <a href="http://en.wikipedia.org/wiki/Brainfuck" target="_blank">BrainFuck</a>. It works for the most part though I have had it do odd stuff but I&#8217;m not sure why, I&#8217;ll revisit it later perhaps. You can download the code <a href="http://codeology.lloydkinsella.net/downloads/oxyfuck.zip" target="_blank">here</a>.<br/><br/>It&#8217;s in <a href="http://www.remobjects.com/oxygene.aspx" target="_blank">RemObjects Oxygene</a> but as normal I&#8217;ll consider doing it in C# or VB.NET if people are interested.</p>
]]></content:encoded>
			<wfw:commentRss>http://codeology.lloydkinsella.net/?feed=rss2&amp;p=159</wfw:commentRss>
		</item>
	</channel>
</rss>
