<?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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ed Spencer &#187; extjs</title>
	<atom:link href="http://edspencer.net/tag/extjs/feed" rel="self" type="application/rss+xml" />
	<link>http://edspencer.net</link>
	<description>A Sencha Architect</description>
	<lastBuildDate>Sat, 11 Feb 2012 09:20:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Proxies in Ext JS 4</title>
		<link>http://edspencer.net/2011/02/proxies-extjs-4.html</link>
		<comments>http://edspencer.net/2011/02/proxies-extjs-4.html#comments</comments>
		<pubDate>Wed, 02 Feb 2011 16:22:59 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[Misc]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[reader]]></category>
		<category><![CDATA[sencha]]></category>
		<category><![CDATA[senchatouch]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=583</guid>
		<description><![CDATA[<p>One of the classes that has a lot more prominence in Ext JS 4 is the data Proxy. Proxies are responsible for all of the loading and saving of data in an Ext JS 4 or Sencha Touch application. Whenever you&#8217;re creating, updating, deleting or loading any type of data in your app, you&#8217;re almost certainly doing it via an Ext.data.Proxy.</p>
<p>If you&#8217;ve seen <a href="http://t.co/wTRxmlE">January&#8217;s Sencha newsletter</a> you may have read an article called <a href="http://www.sencha.com/blog/ext-js-4-anatomy-of-a-model/">Anatomy of a Model</a>, which introduces the most commonly-used Proxies. All a Proxy really needs is four functions &#8211; create, read, update and destroy. For an AjaxProxy, each of these will result in an Ajax request being made. For a LocalStorageProxy, the functions will create, read, update or delete records from HTML5 localStorage.</p>
<p>Because Proxies all implement the same interface they&#8217;re completely interchangeable, so you can swap out your data source &#8211; at design time or run time &#8211; without changing any other code. Although the local Proxies like LocalStorageProxy and MemoryProxy are self-contained, the remote Proxies like AjaxProxy and ScriptTagProxy make use of Readers and Writers to encode and decode their data when communicating with the server.</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/02/Proxy-Reader-and-Writer.png" alt="Proxy-Reader-and-Writer" title="Proxy-Reader-and-Writer" width="660" height="289" class="aligncenter size-full wp-image-585" /></p>
<p>Whether we are reading data from a server or preparing data to be sent back, usually we format it as either JSON or XML. Both of our frameworks come with JSON and XML Readers and Writers which handle all of this for you with a very simple API.</p>
<h3>Using a Proxy with a Model</h3>
<p>Proxies are usually used along with either a Model or a Store. The simplest setup is just with a model:</p>
<pre class="brush: jscript;">
var User = Ext.regModel('User', {
    fields: ['id', 'name', 'email'],

    proxy: {
        type: 'rest',
        url : '/users',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});
</pre>
<p>Here we&#8217;ve created a User model with a RestProxy. RestProxy is a special form of AjaxProxy that can automatically figure out Restful urls for our models. The Proxy that we set up features a JsonReader to decode any server responses &#8211; check out the recent <a href="http://www.sencha.com/blog/2011/01/21/countdown-to-ext-js-4-data-package/">data package post</a> on the Sencha blog to see Readers in action.</p>
<p>When we use the following functions on the new User model, the Proxy is called behind the scenes:</p>
<pre class="brush: jscript;">
var user = new User({name: 'Ed Spencer'});

//CREATE: calls the RestProxy's create function because the user has never been saved
user.save();

//UPDATE: calls the RestProxy's update function because it has been saved before
user.set('email', 'ed@sencha.com');

//DESTROY: calls the RestProxy's destroy function
user.destroy();

//READ: calls the RestProxy's read function
User.load(123, {
    success: function(user) {
        console.log(user);
    }
});
</pre>
<p>We were able to perform all four CRUD operations just by specifying a Proxy for our Model. Notice that the first 3 calls are instance methods whereas the fourth (User.load) is static on the User model. Note also that you can create a Model without a Proxy, you just won&#8217;t be able to persist it.</p>
<h3>Usage with Stores</h3>
<p>In Ext JS 3.x, most of the data manipulation was done via Stores. A chief purpose of a Store is to be a local subset of some data plus delta. For example, you might have 1000 products in your database and have 25 of them loaded into a Store on the client side (the local subset). While operating on that subset, your user may have added, updated or deleted some of the Products. Until these changes are synchronized with the server they are known as a delta.</p>
<p>In order to read data from and sync to the server, Stores also need to be able to call those CRUD operations. We can give a Store a Proxy in the same way:</p>
<pre class="brush: jscript;">
var store = new Ext.data.Store({
    model: 'User',
    proxy: {
        type: 'rest',
        url : '/users',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});
</pre>
<p>We created the exact same Proxy for the Store because that&#8217;s how our server side is set up to deliver data. Because we&#8217;ll usually want to use the same Proxy mechanism for all User manipulations, it&#8217;s usually best to just define the Proxy once on the Model and then simply tell the Store which Model to use. This automatically picks up the User model&#8217;s Proxy:</p>
<pre class="brush: jscript;">
//no need to define proxy - this will reuse the User's Proxy
var store = new Ext.data.Store({
    model: 'User'
});
</pre>
<p>Store invokes the CRUD operations via its <em>load</em> and <em>sync</em> functions. Calling load uses the Proxy&#8217;s read operation, which sync utilizes one or more of create, update and destroy depending on the current Store delta.</p>
<pre class="brush: jscript;">
//CREATE: calls the RestProxy's create function to create the Tommy record on the server
store.add({name: 'Tommy Maintz'});
store.sync();

//UPDATE: calls the RestProxy's update function to update the Tommy record on the server
store.getAt(1).set('email', 'tommy@sencha.com');
store.sync();

//DESTROY: calls the RestProxy's destroy function
store.remove(store.getAt(1));
store.sync();

//READ: calls the RestProxy's read function
store.load();
</pre>
<p>Store has used the exact same CRUD operations on the shared Proxy. In all of the examples above we have used the exact same RestProxy instance from three different places: statically on our Model (User.load), as a Model instance method (user.save, user.destroy) and via a Store instance (store.load, store.sync):</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/02/Proxy-reuse.png" alt="Proxy-reuse" title="Proxy-reuse" width="599" height="236" class="aligncenter size-full wp-image-598" /></p>
<p>Of course, most Proxies have their own private methods to do the actual work, but all a Proxy needs to do is implement those four functions to be usable with Ext JS 4 and Sencha Touch. This means it&#8217;s easy to create new Proxies, as James Pearce did in a <a href="http://www.sencha.com/learn/Tutorial:A_Sencha_Touch_MVC_application_with_PhoneGap">recent Sencha Touch example</a> where he needed to read address book data from a mobile phone. Everything he does to set up his Proxy <a href="http://www.sencha.com/learn/Tutorial:A_Sencha_Touch_MVC_application_with_PhoneGap">in the article</a> (about 1/3rd of the way down) works the same way for Ext JS 4 too.</p>
]]></description>
			<content:encoded><![CDATA[<p>One of the classes that has a lot more prominence in Ext JS 4 is the data Proxy. Proxies are responsible for all of the loading and saving of data in an Ext JS 4 or Sencha Touch application. Whenever you&#8217;re creating, updating, deleting or loading any type of data in your app, you&#8217;re almost certainly doing it via an Ext.data.Proxy.</p>
<p>If you&#8217;ve seen <a href="http://t.co/wTRxmlE">January&#8217;s Sencha newsletter</a> you may have read an article called <a href="http://www.sencha.com/blog/ext-js-4-anatomy-of-a-model/">Anatomy of a Model</a>, which introduces the most commonly-used Proxies. All a Proxy really needs is four functions &#8211; create, read, update and destroy. For an AjaxProxy, each of these will result in an Ajax request being made. For a LocalStorageProxy, the functions will create, read, update or delete records from HTML5 localStorage.</p>
<p>Because Proxies all implement the same interface they&#8217;re completely interchangeable, so you can swap out your data source &#8211; at design time or run time &#8211; without changing any other code. Although the local Proxies like LocalStorageProxy and MemoryProxy are self-contained, the remote Proxies like AjaxProxy and ScriptTagProxy make use of Readers and Writers to encode and decode their data when communicating with the server.</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/02/Proxy-Reader-and-Writer.png" alt="Proxy-Reader-and-Writer" title="Proxy-Reader-and-Writer" width="660" height="289" class="aligncenter size-full wp-image-585" /></p>
<p>Whether we are reading data from a server or preparing data to be sent back, usually we format it as either JSON or XML. Both of our frameworks come with JSON and XML Readers and Writers which handle all of this for you with a very simple API.</p>
<h3>Using a Proxy with a Model</h3>
<p>Proxies are usually used along with either a Model or a Store. The simplest setup is just with a model:</p>
<pre class="brush: jscript;">
var User = Ext.regModel('User', {
    fields: ['id', 'name', 'email'],

    proxy: {
        type: 'rest',
        url : '/users',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});
</pre>
<p>Here we&#8217;ve created a User model with a RestProxy. RestProxy is a special form of AjaxProxy that can automatically figure out Restful urls for our models. The Proxy that we set up features a JsonReader to decode any server responses &#8211; check out the recent <a href="http://www.sencha.com/blog/2011/01/21/countdown-to-ext-js-4-data-package/">data package post</a> on the Sencha blog to see Readers in action.</p>
<p>When we use the following functions on the new User model, the Proxy is called behind the scenes:</p>
<pre class="brush: jscript;">
var user = new User({name: 'Ed Spencer'});

//CREATE: calls the RestProxy's create function because the user has never been saved
user.save();

//UPDATE: calls the RestProxy's update function because it has been saved before
user.set('email', 'ed@sencha.com');

//DESTROY: calls the RestProxy's destroy function
user.destroy();

//READ: calls the RestProxy's read function
User.load(123, {
    success: function(user) {
        console.log(user);
    }
});
</pre>
<p>We were able to perform all four CRUD operations just by specifying a Proxy for our Model. Notice that the first 3 calls are instance methods whereas the fourth (User.load) is static on the User model. Note also that you can create a Model without a Proxy, you just won&#8217;t be able to persist it.</p>
<h3>Usage with Stores</h3>
<p>In Ext JS 3.x, most of the data manipulation was done via Stores. A chief purpose of a Store is to be a local subset of some data plus delta. For example, you might have 1000 products in your database and have 25 of them loaded into a Store on the client side (the local subset). While operating on that subset, your user may have added, updated or deleted some of the Products. Until these changes are synchronized with the server they are known as a delta.</p>
<p>In order to read data from and sync to the server, Stores also need to be able to call those CRUD operations. We can give a Store a Proxy in the same way:</p>
<pre class="brush: jscript;">
var store = new Ext.data.Store({
    model: 'User',
    proxy: {
        type: 'rest',
        url : '/users',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});
</pre>
<p>We created the exact same Proxy for the Store because that&#8217;s how our server side is set up to deliver data. Because we&#8217;ll usually want to use the same Proxy mechanism for all User manipulations, it&#8217;s usually best to just define the Proxy once on the Model and then simply tell the Store which Model to use. This automatically picks up the User model&#8217;s Proxy:</p>
<pre class="brush: jscript;">
//no need to define proxy - this will reuse the User's Proxy
var store = new Ext.data.Store({
    model: 'User'
});
</pre>
<p>Store invokes the CRUD operations via its <em>load</em> and <em>sync</em> functions. Calling load uses the Proxy&#8217;s read operation, which sync utilizes one or more of create, update and destroy depending on the current Store delta.</p>
<pre class="brush: jscript;">
//CREATE: calls the RestProxy's create function to create the Tommy record on the server
store.add({name: 'Tommy Maintz'});
store.sync();

//UPDATE: calls the RestProxy's update function to update the Tommy record on the server
store.getAt(1).set('email', 'tommy@sencha.com');
store.sync();

//DESTROY: calls the RestProxy's destroy function
store.remove(store.getAt(1));
store.sync();

//READ: calls the RestProxy's read function
store.load();
</pre>
<p>Store has used the exact same CRUD operations on the shared Proxy. In all of the examples above we have used the exact same RestProxy instance from three different places: statically on our Model (User.load), as a Model instance method (user.save, user.destroy) and via a Store instance (store.load, store.sync):</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/02/Proxy-reuse.png" alt="Proxy-reuse" title="Proxy-reuse" width="599" height="236" class="aligncenter size-full wp-image-598" /></p>
<p>Of course, most Proxies have their own private methods to do the actual work, but all a Proxy needs to do is implement those four functions to be usable with Ext JS 4 and Sencha Touch. This means it&#8217;s easy to create new Proxies, as James Pearce did in a <a href="http://www.sencha.com/learn/Tutorial:A_Sencha_Touch_MVC_application_with_PhoneGap">recent Sencha Touch example</a> where he needed to read address book data from a mobile phone. Everything he does to set up his Proxy <a href="http://www.sencha.com/learn/Tutorial:A_Sencha_Touch_MVC_application_with_PhoneGap">in the article</a> (about 1/3rd of the way down) works the same way for Ext JS 4 too.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2011/02/proxies-extjs-4.html/feed</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>Introduction to Ext JS 4</title>
		<link>http://edspencer.net/2011/01/introducing-ext-js-4.html</link>
		<comments>http://edspencer.net/2011/01/introducing-ext-js-4.html#comments</comments>
		<pubDate>Thu, 27 Jan 2011 16:30:20 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[extjs4]]></category>
		<category><![CDATA[senchacon]]></category>
		<category><![CDATA[talk]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=566</guid>
		<description><![CDATA[<p>At the end of last 2010 we capped off an incredible year with SenchaCon &#8211; by far the biggest gathering of Sencha developers ever assembled. We descended on San Francisco, 500 strong, and spent an amazing few days sharing the awesome new stuff we&#8217;re working on, learning from each other, and addressing the web&#8217;s most pressing problems.</p>
<p>Now, we&#8217;re proud to release <a href="http://www.sencha.com/conference/sessions/videos.php">all of the videos</a> from the conference completely free for everyone. You can see a <a href="http://www.sencha.com/conference/sessions/videos.php">full list</a> on our conference site, where you&#8217;ll find days worth of material all about Ext JS 4, Sencha Touch and all of the other treats we&#8217;re working on at the moment. </p>
<p>Some of the videos in particular stand out for me &#8211; Jamie&#8217;s <a href="http://vimeo.com/17673342">Charting</a> and <a href="http://vimeo.com/17917111">Layouts</a> talks were spectacular, as was Rob&#8217;s <a href="http://vimeo.com/19159630">Theming Ext JS 4</a> talk. On the Touch side, Tommy&#8217;s talks on <a href="http://vimeo.com/17699976">Performance</a> and <a href="http://vimeo.com/17853133">Debugging</a> are required viewing, as is Dave Kaneda&#8217;s characteristically off the cuff <a href="http://vimeo.com/17705448">Theming</a> talk.</p>
<p>My personal high point was standing in front of all of you and introducing Ext JS 4 and its three core goals &#8211; speed, stability and ease of use. I think you&#8217;re going to love what we&#8217;ve done with the framework in version 4, but for now I&#8217;ll let the video do the talking:</p>
<p><iframe src="http://player.vimeo.com/video/17666102" width="650" height="380" frameborder="0"></iframe></p>
<p>If you&#8217;re so inclined, you can find the <a href="http://www.slideshare.net/edspencer/intro-to-ext-4">slides for this talk</a> on slideshare, and if you can still stand the sound of my voice check out my other presentation on <a href="http://vimeo.com/17733892">Ext JS 4 Architecture</a>, focusing chiefly on the new data package (<a href="http://www.slideshare.net/edspencer/ext-js-4-architecture">slides</a>).</p>
]]></description>
			<content:encoded><![CDATA[<p>At the end of last 2010 we capped off an incredible year with SenchaCon &#8211; by far the biggest gathering of Sencha developers ever assembled. We descended on San Francisco, 500 strong, and spent an amazing few days sharing the awesome new stuff we&#8217;re working on, learning from each other, and addressing the web&#8217;s most pressing problems.</p>
<p>Now, we&#8217;re proud to release <a href="http://www.sencha.com/conference/sessions/videos.php">all of the videos</a> from the conference completely free for everyone. You can see a <a href="http://www.sencha.com/conference/sessions/videos.php">full list</a> on our conference site, where you&#8217;ll find days worth of material all about Ext JS 4, Sencha Touch and all of the other treats we&#8217;re working on at the moment. </p>
<p>Some of the videos in particular stand out for me &#8211; Jamie&#8217;s <a href="http://vimeo.com/17673342">Charting</a> and <a href="http://vimeo.com/17917111">Layouts</a> talks were spectacular, as was Rob&#8217;s <a href="http://vimeo.com/19159630">Theming Ext JS 4</a> talk. On the Touch side, Tommy&#8217;s talks on <a href="http://vimeo.com/17699976">Performance</a> and <a href="http://vimeo.com/17853133">Debugging</a> are required viewing, as is Dave Kaneda&#8217;s characteristically off the cuff <a href="http://vimeo.com/17705448">Theming</a> talk.</p>
<p>My personal high point was standing in front of all of you and introducing Ext JS 4 and its three core goals &#8211; speed, stability and ease of use. I think you&#8217;re going to love what we&#8217;ve done with the framework in version 4, but for now I&#8217;ll let the video do the talking:</p>
<p><iframe src="http://player.vimeo.com/video/17666102" width="650" height="380" frameborder="0"></iframe></p>
<p>If you&#8217;re so inclined, you can find the <a href="http://www.slideshare.net/edspencer/intro-to-ext-4">slides for this talk</a> on slideshare, and if you can still stand the sound of my voice check out my other presentation on <a href="http://vimeo.com/17733892">Ext JS 4 Architecture</a>, focusing chiefly on the new data package (<a href="http://www.slideshare.net/edspencer/ext-js-4-architecture">slides</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2011/01/introducing-ext-js-4.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Ext JS 4: The Class Definition Pipeline</title>
		<link>http://edspencer.net/2011/01/ext-js-4-the-class-definition-pipeline.html</link>
		<comments>http://edspencer.net/2011/01/ext-js-4-the-class-definition-pipeline.html#comments</comments>
		<pubDate>Tue, 25 Jan 2011 16:25:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[Misc]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[extjs4]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=538</guid>
		<description><![CDATA[<p>Last time, we looked at some of the features of the <a href="http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html">new class system in Ext JS 4</a>, and explored some of the code that makes it work. Today we&#8217;re going to dig a little deeper and look at the class definition pipeline &#8211; the framework responsible for creating every class in Ext JS 4.</p>
<p><a href="http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html">As I mentioned last time</a>, every class in Ext JS 4 is an instance of Ext.Class. When an Ext.Class is constructed, it hands itself off to a pipeline populated by small, focused processors, each of which handles one part of the class definition process. We ship a number of these processors out of the box &#8211; there are processors for handling mixins, setting up configuration functions and handling class extension.</p>
<p>The pipeline is probably best explained with a picture. Think of your class starting its definition journey at the bottom left, working its way up the preprocessors on the left hand side and then down the postprocessors on the right, until finally it reaches the end, where it signals its readiness to a callback function:</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/01/Processors.png" alt="Ext JS 4 Class Definition Pipeline" title="Ext JS 4 Class Definition Pipeline" width="687" height="537" class="aligncenter size-full wp-image-528" /></p>
<p>The distinction between preprocessors and postprocessors is that a class is considered ‘ready’ (e.g. can be instantiated) after the preprocessors have all been executed. Postprocessors typically perform functions like aliasing the class name to an xtype or back to a legacy class name &#8211; things that don&#8217;t affect the class&#8217; behavior.</p>
<p>Each processor runs asynchronously, calling back to the Ext.Class constructor when it is ready &#8211; this is what enables us to extend classes that don’t exist on the page yet. The first preprocessor is the Loader, which checks to see if all of the new Class’ dependencies are available. If they are not, the Loader can dynamically load those dependencies before calling back to Ext.Class and allowing the next preprocessor to run. We&#8217;ll take another look at the Loader in another post.</p>
<p>After running the Loader, the new Class is set up to inherit from the declared superclass by the Extend preprocessor. The Mixins preprocessor takes care of copying all of the functions from each of our mixins, and the Config preprocessor handles the creation of the 4 config functions we saw last time (e.g. getTitle, setTitle, resetTitle, applyTitle &#8211; check out <a href="http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html">yesterday&#8217;s post</a> to see how the Configs processor helps out).</p>
<p>Finally, the Statics preprocessor looks for any static functions that we set up on our new class and makes them available statically on the class. The processors that are run are completely customizable, and it’s easy to add custom processors at any point. Let&#8217;s take a look at that Statics preprocessor as an example:</p>
<pre class="brush: jscript;">
//Each processor is passed three arguments - the class under construction,
//the configuration for that class and a callback function to call when the processor has finished
Ext.Class.registerPreprocessor('statics', function(cls, data, callback) {
    if (Ext.isObject(data.statics)) {
        var statics = data.statics,
            name;

        //here we just copy each static function onto the new Class
        for (name in statics) {
            if (statics.hasOwnProperty(name)) {
                cls[name] = statics[name];
            }
        }
    }

    delete data.statics;

    //Once the processor's work is done, we just call the callback function to kick off the next processor
    if (callback) {
        callback.call(this, cls, data);
    }
});

//Changing the order that the preprocessors are called in is easy too - this is the default
Ext.Class.setDefaultPreprocessors(['extend', 'mixins', 'config', 'statics']);
</pre>
<p>What happens above is pretty straightforward. We&#8217;re registering a preprocessor called &#8217;statics&#8217; with Ext.Class. The function we provide is called whenever the &#8217;statics&#8217; preprocessor is invoked, and is passed the new Ext.Class instance, the configuration for that class, and a callback to call when the preprocessor has finished its work.</p>
<p>The actual work that this preprocessor does is trivial &#8211; it just looks to see if we declared a &#8217;statics&#8217; property in our class configuration and if so copies it onto the new class. For example, let&#8217;s say we want to create a static getNextId function on a class:</p>
<pre class="brush: jscript;">
Ext.define('MyClass', {
    statics: {
        idSeed: 1000,
        getNextId: function() {
            return this.idSeed++;
        }
    }
});
</pre>
<p>Because of the Statics preprocessor, we can now call the function statically on the Class (e.g. without creating an instance of MyClass):</p>
<pre class="brush: jscript;">
MyClass.getNextId(); //1000
MyClass.getNextId(); //1001
MyClass.getNextId(); //1002
... etc
</pre>
<p>Finally, let&#8217;s come back to that callback at the bottom of the picture above. If we supply one, a callback function is run after all of the processors have run. At this point the new class is completely ready for use in your application. Here we create an instance of MyClass using the callback function, guaranteeing that the dependency on Ext.Window has been honored:</p>
<pre class="brush: jscript;">
Ext.define('MyClass', {
    extend: 'Ext.Window'
}, function() {
   //this callback is called when MyClass is ready for use
   var cls = new MyClass();
   cls.setTitle('Everything is ready');
   cls.show();
});
</pre>
<p>That&#8217;s it for today. Next time we&#8217;ll look at some of the new features in the part of Ext JS 4 that is closest to my heart &#8211; the data package.</p>
]]></description>
			<content:encoded><![CDATA[<p>Last time, we looked at some of the features of the <a href="http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html">new class system in Ext JS 4</a>, and explored some of the code that makes it work. Today we&#8217;re going to dig a little deeper and look at the class definition pipeline &#8211; the framework responsible for creating every class in Ext JS 4.</p>
<p><a href="http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html">As I mentioned last time</a>, every class in Ext JS 4 is an instance of Ext.Class. When an Ext.Class is constructed, it hands itself off to a pipeline populated by small, focused processors, each of which handles one part of the class definition process. We ship a number of these processors out of the box &#8211; there are processors for handling mixins, setting up configuration functions and handling class extension.</p>
<p>The pipeline is probably best explained with a picture. Think of your class starting its definition journey at the bottom left, working its way up the preprocessors on the left hand side and then down the postprocessors on the right, until finally it reaches the end, where it signals its readiness to a callback function:</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/01/Processors.png" alt="Ext JS 4 Class Definition Pipeline" title="Ext JS 4 Class Definition Pipeline" width="687" height="537" class="aligncenter size-full wp-image-528" /></p>
<p>The distinction between preprocessors and postprocessors is that a class is considered ‘ready’ (e.g. can be instantiated) after the preprocessors have all been executed. Postprocessors typically perform functions like aliasing the class name to an xtype or back to a legacy class name &#8211; things that don&#8217;t affect the class&#8217; behavior.</p>
<p>Each processor runs asynchronously, calling back to the Ext.Class constructor when it is ready &#8211; this is what enables us to extend classes that don’t exist on the page yet. The first preprocessor is the Loader, which checks to see if all of the new Class’ dependencies are available. If they are not, the Loader can dynamically load those dependencies before calling back to Ext.Class and allowing the next preprocessor to run. We&#8217;ll take another look at the Loader in another post.</p>
<p>After running the Loader, the new Class is set up to inherit from the declared superclass by the Extend preprocessor. The Mixins preprocessor takes care of copying all of the functions from each of our mixins, and the Config preprocessor handles the creation of the 4 config functions we saw last time (e.g. getTitle, setTitle, resetTitle, applyTitle &#8211; check out <a href="http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html">yesterday&#8217;s post</a> to see how the Configs processor helps out).</p>
<p>Finally, the Statics preprocessor looks for any static functions that we set up on our new class and makes them available statically on the class. The processors that are run are completely customizable, and it’s easy to add custom processors at any point. Let&#8217;s take a look at that Statics preprocessor as an example:</p>
<pre class="brush: jscript;">
//Each processor is passed three arguments - the class under construction,
//the configuration for that class and a callback function to call when the processor has finished
Ext.Class.registerPreprocessor('statics', function(cls, data, callback) {
    if (Ext.isObject(data.statics)) {
        var statics = data.statics,
            name;

        //here we just copy each static function onto the new Class
        for (name in statics) {
            if (statics.hasOwnProperty(name)) {
                cls[name] = statics[name];
            }
        }
    }

    delete data.statics;

    //Once the processor's work is done, we just call the callback function to kick off the next processor
    if (callback) {
        callback.call(this, cls, data);
    }
});

//Changing the order that the preprocessors are called in is easy too - this is the default
Ext.Class.setDefaultPreprocessors(['extend', 'mixins', 'config', 'statics']);
</pre>
<p>What happens above is pretty straightforward. We&#8217;re registering a preprocessor called &#8217;statics&#8217; with Ext.Class. The function we provide is called whenever the &#8217;statics&#8217; preprocessor is invoked, and is passed the new Ext.Class instance, the configuration for that class, and a callback to call when the preprocessor has finished its work.</p>
<p>The actual work that this preprocessor does is trivial &#8211; it just looks to see if we declared a &#8217;statics&#8217; property in our class configuration and if so copies it onto the new class. For example, let&#8217;s say we want to create a static getNextId function on a class:</p>
<pre class="brush: jscript;">
Ext.define('MyClass', {
    statics: {
        idSeed: 1000,
        getNextId: function() {
            return this.idSeed++;
        }
    }
});
</pre>
<p>Because of the Statics preprocessor, we can now call the function statically on the Class (e.g. without creating an instance of MyClass):</p>
<pre class="brush: jscript;">
MyClass.getNextId(); //1000
MyClass.getNextId(); //1001
MyClass.getNextId(); //1002
... etc
</pre>
<p>Finally, let&#8217;s come back to that callback at the bottom of the picture above. If we supply one, a callback function is run after all of the processors have run. At this point the new class is completely ready for use in your application. Here we create an instance of MyClass using the callback function, guaranteeing that the dependency on Ext.Window has been honored:</p>
<pre class="brush: jscript;">
Ext.define('MyClass', {
    extend: 'Ext.Window'
}, function() {
   //this callback is called when MyClass is ready for use
   var cls = new MyClass();
   cls.setTitle('Everything is ready');
   cls.show();
});
</pre>
<p>That&#8217;s it for today. Next time we&#8217;ll look at some of the new features in the part of Ext JS 4 that is closest to my heart &#8211; the data package.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2011/01/ext-js-4-the-class-definition-pipeline.html/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Classes in Ext JS 4: Under the hood</title>
		<link>http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html</link>
		<comments>http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html#comments</comments>
		<pubDate>Mon, 24 Jan 2011 16:37:22 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[dynamic loading]]></category>
		<category><![CDATA[extjs4]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=518</guid>
		<description><![CDATA[<p>Last week we unveiled a the brand new class system coming in Ext JS 4. If you haven’t seen the new system in action I hope you’ll take a look at the <a href="http://www.sencha.com/blog/2011/01/19/countdown-to-ext-js-4-dynamic-loading-and-new-class-system/">blog post</a> on sencha.com and check out the <a href="http://dev.sencha.com/deploy/LoaderDemo/">live demo</a>. Today we’re going to dig a little deeper into the class system to see how it actually works.</p>
<p>To briefly recap, the new class system enables us to define classes like this:</p>
<pre class="brush: jscript;">
Ext.define('Ext.Window', {
    extend: 'Ext.Panel',
    requires: 'Ext.Tool',
    mixins: {
        draggable: 'Ext.util.Draggable'
    },

    config: {
        title: &quot;Window Title&quot;
    }
});
</pre>
<p>Here we’ve set up a slightly simplified version of the Ext.Window class. We’ve set Window up to be a subclass of Panel, declared that it requires the Ext.Tool class and that it mixes in functionality from the Ext.util.Draggable class.</p>
<p>There are a few new things here so we’ll attack them one at a time. The ‘extend’ declaration does what you’d expect &#8211; we’re just saying that Window should be a subclass of Panel. The ‘requires’ declaration means that the named classes (just Ext.Tool in this case) have to be present before the Window class can be considered ‘ready’ for use (more on class readiness in a moment).</p>
<p>The ‘mixins’ declaration is a brand new concept when it comes to Ext JS. A mixin is just a set of functions (and sometimes properties) that are merged into a class. For example, the Ext.util.Draggable mixin we defined above might contain a function called ‘startDragging’ &#8211; this gets copied into Ext.Window to enable us to use the function in a window instance:</p>
<pre class="brush: jscript;">
//a simplified Draggable mixin
Ext.define('Ext.util.Draggable', {
    startDragging: function() {
        console.log('started dragging');
    }
});
</pre>
<p>When we create a new Ext.Window instance now, we can call the function that was mixed in from Ext.util.Draggable:</p>
<pre class="brush: jscript;">
var win = Ext.create('Ext.Window');
win.startDragging(); //&quot;started dragging&quot;
</pre>
<p>Mixins are really useful when a class needs to inherit multiple traits but can’t do so easily using a traditional single inheritance mechanism. For example, Ext.Windows is a draggable component, as are Sliders, Grid headers, and many other UI elements. Because this behavior crops up in many different places it’s not feasible to work the draggable behavior into a single superclass because not all of those UI elements actually share a common superclass. Creating a Draggable mixin solves this problem &#8211; now anything can be made draggable with a couple of lines of code.</p>
<p>The last new piece of functionality I’ll mention briefly is the ‘config’ declaration. Most of the classes in Ext JS take configuration parameters, many of which can be changed at runtime. In the Ext.Window above example we declared that the class has a ‘title’ configuration, which takes the default value of ‘Window Title’. By setting the class up like this we get 4 methods for free &#8211; getTitle, setTitle, resetTitle and applyTitle.</p>
<ul>
<li><b>getTitle</b> &#8211; returns the current title</li>
<li><b>setTitle</b> &#8211; sets the title to a new value</li>
<li><b>resetTitle</b> &#8211;  reverts the title to its default value (‘Window Title’)</li>
<li><b>applyTitle</b> &#8211; this is a template method that you can choose to define. It is called whenever setTitle is called.
</ul>
<p>The applyTitle function is the place to put any logic that needs to be called when the title is changed &#8211; for example we might want to update a DOM Element with the new title:</p>
<pre class="brush: jscript;">
Ext.define(‘Ext.Window’, {
    //..as above,

    config: {
        title: 'Window Title'
    },

    //updates the DOM element that contains the window title
    applyTitle: function(newTitle) {
        this.titleEl.update(newTitle);
    }
});
</pre>
<p>This saves us a lot of time and code while providing a consistent API for all configuration options: win-win.</p>
<h3>Digging Deeper</h3>
<p>Ext JS 4 introduces 4 new classes to make all this magic work:</p>
<ul>
<li><b>Ext.Base</b> &#8211; all classes inherit from Ext.Base. It provides basic low-level functionality used by all classes</li>
<li><b>Ext.Class</b> &#8211; a factory for making new classes</li>
<li><b>Ext.ClassLoader</b> &#8211; responsible for ensuring that classes are available, loading them if they aren’t on the page already</li>
<li><b>Ext.ClassManager</b> &#8211; kicks off class creation and manages dependencies</li>
</ul>
<p>These all work together behind the scenes and most of the time you won’t even need to be aware of what is being called when you define and use a class. The two functions that you’ll use most often &#8211; Ext.define and Ext.create &#8211; both call Ext.ClassManager under the hood, which in turn utilizes the other three classes to put everything together.</p>
<p>The distinction between Ext.Class and Ext.Base is important. Ext.Base is the top-level <i>superclass</i> for every class ever defined &#8211; every class inherits from Ext.Base at some point. Ext.Class represents the class itself &#8211; every class you define is an <i>instance</i> of Ext.Class, and a <i>subclass</i> of Ext.Base. To illustrate, let’s say we created a class called MyClass, which doesn’t extend any other class:</p>
<pre class="brush: jscript;">
Ext.define('MyClass', {
    someFunction: function() {
        console.log('Ran some function');
    }
});
</pre>
<p>The direct superclass for MyClass is Ext.Base because we didn’t specify that MyClass should extend anything else. If you imagine a tree of all the classes we’ve defined so far, it will look something like this:</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/01/Sample-inheritance-tree.png" alt="Sample-inheritance-tree" title="Sample-inheritance-tree" width="435" height="398" class="aligncenter size-full wp-image-522" /></p>
<p>This tree bases its hierarchy on the inheritance structure of our classes, and the root is always Ext.Base &#8211; that is, every class eventually inherits from Ext.Base. So every item in the diagram above is a <i>subclass</i> of Ext.Base, but every item is also an <i>instance</i> of Ext.Class. Classes themselves are instances of Ext.Class, which means we can easily modify the Class at a later time &#8211; for example mixing in additional functionality:</p>
<pre class="brush: jscript;">
//we can define some mixins at definition time
Ext.define('MyClass', {
    mixins: {
        observable: 'Ext.util.Observable'
    }
});

//it’s easy to add more later too
MyClass.mixin('draggable', 'Ext.util.Draggable');
</pre>
<p>This architecture opens up new possibilities for dynamic class creation and metaprogramming, which were difficult to pull off in earlier versions.</p>
<p>In the next episode, we’ll look at how the class definition pipeline is structured and how to extend it to add your own features.</p>
]]></description>
			<content:encoded><![CDATA[<p>Last week we unveiled a the brand new class system coming in Ext JS 4. If you haven’t seen the new system in action I hope you’ll take a look at the <a href="http://www.sencha.com/blog/2011/01/19/countdown-to-ext-js-4-dynamic-loading-and-new-class-system/">blog post</a> on sencha.com and check out the <a href="http://dev.sencha.com/deploy/LoaderDemo/">live demo</a>. Today we’re going to dig a little deeper into the class system to see how it actually works.</p>
<p>To briefly recap, the new class system enables us to define classes like this:</p>
<pre class="brush: jscript;">
Ext.define('Ext.Window', {
    extend: 'Ext.Panel',
    requires: 'Ext.Tool',
    mixins: {
        draggable: 'Ext.util.Draggable'
    },

    config: {
        title: &quot;Window Title&quot;
    }
});
</pre>
<p>Here we’ve set up a slightly simplified version of the Ext.Window class. We’ve set Window up to be a subclass of Panel, declared that it requires the Ext.Tool class and that it mixes in functionality from the Ext.util.Draggable class.</p>
<p>There are a few new things here so we’ll attack them one at a time. The ‘extend’ declaration does what you’d expect &#8211; we’re just saying that Window should be a subclass of Panel. The ‘requires’ declaration means that the named classes (just Ext.Tool in this case) have to be present before the Window class can be considered ‘ready’ for use (more on class readiness in a moment).</p>
<p>The ‘mixins’ declaration is a brand new concept when it comes to Ext JS. A mixin is just a set of functions (and sometimes properties) that are merged into a class. For example, the Ext.util.Draggable mixin we defined above might contain a function called ‘startDragging’ &#8211; this gets copied into Ext.Window to enable us to use the function in a window instance:</p>
<pre class="brush: jscript;">
//a simplified Draggable mixin
Ext.define('Ext.util.Draggable', {
    startDragging: function() {
        console.log('started dragging');
    }
});
</pre>
<p>When we create a new Ext.Window instance now, we can call the function that was mixed in from Ext.util.Draggable:</p>
<pre class="brush: jscript;">
var win = Ext.create('Ext.Window');
win.startDragging(); //&quot;started dragging&quot;
</pre>
<p>Mixins are really useful when a class needs to inherit multiple traits but can’t do so easily using a traditional single inheritance mechanism. For example, Ext.Windows is a draggable component, as are Sliders, Grid headers, and many other UI elements. Because this behavior crops up in many different places it’s not feasible to work the draggable behavior into a single superclass because not all of those UI elements actually share a common superclass. Creating a Draggable mixin solves this problem &#8211; now anything can be made draggable with a couple of lines of code.</p>
<p>The last new piece of functionality I’ll mention briefly is the ‘config’ declaration. Most of the classes in Ext JS take configuration parameters, many of which can be changed at runtime. In the Ext.Window above example we declared that the class has a ‘title’ configuration, which takes the default value of ‘Window Title’. By setting the class up like this we get 4 methods for free &#8211; getTitle, setTitle, resetTitle and applyTitle.</p>
<ul>
<li><b>getTitle</b> &#8211; returns the current title</li>
<li><b>setTitle</b> &#8211; sets the title to a new value</li>
<li><b>resetTitle</b> &#8211;  reverts the title to its default value (‘Window Title’)</li>
<li><b>applyTitle</b> &#8211; this is a template method that you can choose to define. It is called whenever setTitle is called.
</ul>
<p>The applyTitle function is the place to put any logic that needs to be called when the title is changed &#8211; for example we might want to update a DOM Element with the new title:</p>
<pre class="brush: jscript;">
Ext.define(‘Ext.Window’, {
    //..as above,

    config: {
        title: 'Window Title'
    },

    //updates the DOM element that contains the window title
    applyTitle: function(newTitle) {
        this.titleEl.update(newTitle);
    }
});
</pre>
<p>This saves us a lot of time and code while providing a consistent API for all configuration options: win-win.</p>
<h3>Digging Deeper</h3>
<p>Ext JS 4 introduces 4 new classes to make all this magic work:</p>
<ul>
<li><b>Ext.Base</b> &#8211; all classes inherit from Ext.Base. It provides basic low-level functionality used by all classes</li>
<li><b>Ext.Class</b> &#8211; a factory for making new classes</li>
<li><b>Ext.ClassLoader</b> &#8211; responsible for ensuring that classes are available, loading them if they aren’t on the page already</li>
<li><b>Ext.ClassManager</b> &#8211; kicks off class creation and manages dependencies</li>
</ul>
<p>These all work together behind the scenes and most of the time you won’t even need to be aware of what is being called when you define and use a class. The two functions that you’ll use most often &#8211; Ext.define and Ext.create &#8211; both call Ext.ClassManager under the hood, which in turn utilizes the other three classes to put everything together.</p>
<p>The distinction between Ext.Class and Ext.Base is important. Ext.Base is the top-level <i>superclass</i> for every class ever defined &#8211; every class inherits from Ext.Base at some point. Ext.Class represents the class itself &#8211; every class you define is an <i>instance</i> of Ext.Class, and a <i>subclass</i> of Ext.Base. To illustrate, let’s say we created a class called MyClass, which doesn’t extend any other class:</p>
<pre class="brush: jscript;">
Ext.define('MyClass', {
    someFunction: function() {
        console.log('Ran some function');
    }
});
</pre>
<p>The direct superclass for MyClass is Ext.Base because we didn’t specify that MyClass should extend anything else. If you imagine a tree of all the classes we’ve defined so far, it will look something like this:</p>
<p><img src="http://edspencer.net/wp-content/uploads/2011/01/Sample-inheritance-tree.png" alt="Sample-inheritance-tree" title="Sample-inheritance-tree" width="435" height="398" class="aligncenter size-full wp-image-522" /></p>
<p>This tree bases its hierarchy on the inheritance structure of our classes, and the root is always Ext.Base &#8211; that is, every class eventually inherits from Ext.Base. So every item in the diagram above is a <i>subclass</i> of Ext.Base, but every item is also an <i>instance</i> of Ext.Class. Classes themselves are instances of Ext.Class, which means we can easily modify the Class at a later time &#8211; for example mixing in additional functionality:</p>
<pre class="brush: jscript;">
//we can define some mixins at definition time
Ext.define('MyClass', {
    mixins: {
        observable: 'Ext.util.Observable'
    }
});

//it’s easy to add more later too
MyClass.mixin('draggable', 'Ext.util.Draggable');
</pre>
<p>This architecture opens up new possibilities for dynamic class creation and metaprogramming, which were difficult to pull off in earlier versions.</p>
<p>In the next episode, we’ll look at how the class definition pipeline is structured and how to extend it to add your own features.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2011/01/classes-in-ext-js-4-under-the-hood.html/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Using the Ext JS PivotGrid</title>
		<link>http://edspencer.net/2010/07/using-the-ext-js-pivotgrid.html</link>
		<comments>http://edspencer.net/2010/07/using-the-ext-js-pivotgrid.html#comments</comments>
		<pubDate>Thu, 29 Jul 2010 19:10:13 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[3.3]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[pivotgrid]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[stores]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=479</guid>
		<description><![CDATA[<p>One of the new components we just unveiled for the <a href="http://www.sencha.com/blog/2010/07/28/announcing-ext-js-3-3-beta-pivotgrids-calendars-and-more/">Ext JS 3.3 beta</a> is PivotGrid. PivotGrid is a powerful new component that reduces and aggregates large datasets into a more understandable form.</p>
<p>A classic example of PivotGrid&#8217;s usefulness is in analyzing sales data. Companies often keep a database containing all the sales they have made and want to glean some insight into how well they are performing. PivotGrid gives the ability to rapidly summarize this large and unwieldy dataset &#8211; for example showing sales count broken down by city and salesperson.</p>
<h2>A simple example</h2>
<p>We created <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.html">an example of this scenario</a> in the 3.3 beta release. Here we have a fictional dataset containing 300 rows of sales data (<a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.json">see the raw data</a>). We asked PivotGrid to break the data down by Salesperson and Product, showing us how they performed over time. Each cell contains the sum of sales made by the given salesperson/product combination in the given city and year.</p>
<p>Let&#8217;s see how we create this PivotGrid:</p>
<pre class="brush: jscript;">
var SaleRecord = Ext.data.Record.create([
    {name: 'person',   type: 'string'},
    {name: 'product',  type: 'string'},
    {name: 'city',     type: 'string'},
    {name: 'state',    type: 'string'},
    {name: 'month',    type: 'int'},
    {name: 'quarter',  type: 'int'},
    {name: 'year',     type: 'int'},
    {name: 'quantity', type: 'int'},
    {name: 'value',    type: 'int'}
]);

var myStore = new Ext.data.Store({
    url: 'salesdata.json',
    autoLoad: true,
    reader: new Ext.data.JsonReader({
        root: 'rows',
        idProperty: 'id'
    }, SaleRecord)
});

var pivotGrid = new Ext.grid.PivotGrid({
    title     : 'Sales Performance',
    store     : myStore,
    aggregator: 'sum',
    measure   : 'value',

    leftAxis: [
        {dataIndex: 'person',  width: 80},
        {dataIndex: 'product', width: 90}
    ],

    topAxis: [
        {dataIndex: 'year'},
        {dataIndex: 'city'}
    ]
});
</pre>
<p>The first half of this ought to be very familiar &#8211; we just set up a normal Record and Store. This is all we need to load our <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.json">sample data</a> so that it&#8217;s ready for pivoting. This is all exactly the same code as for our other Store-bound components like Grid and DataView so it&#8217;s easy to take an existing Grid and turn it into a PivotGrid.</p>
<p>The second half of the code creates the PivotGrid itself. There are 5 main components to a PivotGrid &#8211; the store, the measure, the aggregator, the left axis and the top axis. Taking these in turn:</p>
<ul>
<li><b>Store</b> &#8211; the Store we created above</li>
<li><b>Measure</b> &#8211; the field in the data that we want to aggregate (in this case the sale value)</li>
<li><b>Aggregator</b> &#8211; the function we use to combine data into the cells. <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/docs/?class=Ext.grid.PivotGrid">See the docs</a> for full details</li>
<li><b>Left Axis</b> &#8211; the fields to break data down by on the left axis</li>
<li><b>Top Axis</b> &#8211; the fields to break data down by on the top axis</li>
</ul>
<p>The measure and the items in the axes must all be fields from the Store. The aggregator function can usually be passed in as a string &#8211; there are 5 aggregator functions built in: sum, count, min, max and avg.</p>
<h2>Renderers</h2>
<p>This is all we need to create a simple PivotGrid; now it&#8217;s time to look at a few more advanced options. Let&#8217;s start with renderers. Once the data for each cell has been calculated, the value is passed to an optional renderer function, which takes each value in turn and returns another value. <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/people.html">One of the PivotGrid examples</a> shows average heights in feet and inches but the calculated data is in decimal. Here&#8217;s the renderer we use in that example:</p>
<pre class="brush: jscript;">
new Ext.grid.PivotGrid({
    store     : myStore,
    aggregator: 'avg',
    measure   : 'height',

    //turns a decimal number of feet into feet and inches
    renderer  : function(value) {
        var feet   = Math.floor(value),
            inches = Math.round((value - feet) * 12);

        return String.format(&quot;{0}' {1}\&quot;&quot;, feet, inches);
    },
    //the rest of the config
});
</pre>
<h2>Customising cell appearance</h2>
<p>Another one of the <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/countries.html">PivotGrid examples uses a custom cell style</a>. As with the renderer, each cell has the opportunity to alter itself with a custom function &#8211; here&#8217;s the one we use in the <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/countries.html">countries example</a>:</p>
<pre class="brush: jscript;">
new Ext.grid.PivotGrid({
    store     : myStore,
    aggregator: 'avg',
    measure   : 'height',

    viewConfig: {
        getCellCls: function(value) {
            if (value &lt; 20) {
                return 'expense-low';
            } else if (value &lt; 75) {
                return 'expense-medium';
            } else {
                return 'expense-high';
            }
        }
    },
    //the rest of the config
});
</pre>
<h2>Reconfiguring at runtime</h2>
<p>A lot of the power of PivotGrid is that it can be used by users of your application to summarize datasets any way they want. This is made possible by PivotGrid&#8217;s ability to reconfigure itself at runtime. We present one final example of a <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/reconfigurable.html">PivotGrid that can be reconfigured at runtime</a>. Here&#8217;s how we perform the reconfiguration:</p>
<pre class="brush: jscript;">
//the left axis can also be changed
pivot.topAxis.setDimensions([
    {dataIndex: 'city', direction: 'DESC'},
    {dataIndex: 'year', direction: 'ASC'}
]);

pivot.setMeasure('value');
pivot.setAggregator('avg');

pivot.view.refresh(true);
</pre>
<p>It&#8217;s easy to change the axes, dimension, aggregator and measure at any time and then refresh the data. The calculations are all performed client side so there is no need for another round-trip to the server when reconfiguring. The example linked above gives an example interface for updating a PivotGrid, though anything that can make the API calls above could be used.</p>
<p>I hope you enjoy the new components in this Ext JS 3.3 beta and look forward to comments and suggestions. Although we&#8217;re only at beta stage I think the additions are already quite robust so feel free to stress-test them.</p>
]]></description>
			<content:encoded><![CDATA[<p>One of the new components we just unveiled for the <a href="http://www.sencha.com/blog/2010/07/28/announcing-ext-js-3-3-beta-pivotgrids-calendars-and-more/">Ext JS 3.3 beta</a> is PivotGrid. PivotGrid is a powerful new component that reduces and aggregates large datasets into a more understandable form.</p>
<p>A classic example of PivotGrid&#8217;s usefulness is in analyzing sales data. Companies often keep a database containing all the sales they have made and want to glean some insight into how well they are performing. PivotGrid gives the ability to rapidly summarize this large and unwieldy dataset &#8211; for example showing sales count broken down by city and salesperson.</p>
<h2>A simple example</h2>
<p>We created <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.html">an example of this scenario</a> in the 3.3 beta release. Here we have a fictional dataset containing 300 rows of sales data (<a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.json">see the raw data</a>). We asked PivotGrid to break the data down by Salesperson and Product, showing us how they performed over time. Each cell contains the sum of sales made by the given salesperson/product combination in the given city and year.</p>
<p>Let&#8217;s see how we create this PivotGrid:</p>
<pre class="brush: jscript;">
var SaleRecord = Ext.data.Record.create([
    {name: 'person',   type: 'string'},
    {name: 'product',  type: 'string'},
    {name: 'city',     type: 'string'},
    {name: 'state',    type: 'string'},
    {name: 'month',    type: 'int'},
    {name: 'quarter',  type: 'int'},
    {name: 'year',     type: 'int'},
    {name: 'quantity', type: 'int'},
    {name: 'value',    type: 'int'}
]);

var myStore = new Ext.data.Store({
    url: 'salesdata.json',
    autoLoad: true,
    reader: new Ext.data.JsonReader({
        root: 'rows',
        idProperty: 'id'
    }, SaleRecord)
});

var pivotGrid = new Ext.grid.PivotGrid({
    title     : 'Sales Performance',
    store     : myStore,
    aggregator: 'sum',
    measure   : 'value',

    leftAxis: [
        {dataIndex: 'person',  width: 80},
        {dataIndex: 'product', width: 90}
    ],

    topAxis: [
        {dataIndex: 'year'},
        {dataIndex: 'city'}
    ]
});
</pre>
<p>The first half of this ought to be very familiar &#8211; we just set up a normal Record and Store. This is all we need to load our <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.json">sample data</a> so that it&#8217;s ready for pivoting. This is all exactly the same code as for our other Store-bound components like Grid and DataView so it&#8217;s easy to take an existing Grid and turn it into a PivotGrid.</p>
<p>The second half of the code creates the PivotGrid itself. There are 5 main components to a PivotGrid &#8211; the store, the measure, the aggregator, the left axis and the top axis. Taking these in turn:</p>
<ul>
<li><b>Store</b> &#8211; the Store we created above</li>
<li><b>Measure</b> &#8211; the field in the data that we want to aggregate (in this case the sale value)</li>
<li><b>Aggregator</b> &#8211; the function we use to combine data into the cells. <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/docs/?class=Ext.grid.PivotGrid">See the docs</a> for full details</li>
<li><b>Left Axis</b> &#8211; the fields to break data down by on the left axis</li>
<li><b>Top Axis</b> &#8211; the fields to break data down by on the top axis</li>
</ul>
<p>The measure and the items in the axes must all be fields from the Store. The aggregator function can usually be passed in as a string &#8211; there are 5 aggregator functions built in: sum, count, min, max and avg.</p>
<h2>Renderers</h2>
<p>This is all we need to create a simple PivotGrid; now it&#8217;s time to look at a few more advanced options. Let&#8217;s start with renderers. Once the data for each cell has been calculated, the value is passed to an optional renderer function, which takes each value in turn and returns another value. <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/people.html">One of the PivotGrid examples</a> shows average heights in feet and inches but the calculated data is in decimal. Here&#8217;s the renderer we use in that example:</p>
<pre class="brush: jscript;">
new Ext.grid.PivotGrid({
    store     : myStore,
    aggregator: 'avg',
    measure   : 'height',

    //turns a decimal number of feet into feet and inches
    renderer  : function(value) {
        var feet   = Math.floor(value),
            inches = Math.round((value - feet) * 12);

        return String.format(&quot;{0}' {1}\&quot;&quot;, feet, inches);
    },
    //the rest of the config
});
</pre>
<h2>Customising cell appearance</h2>
<p>Another one of the <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/countries.html">PivotGrid examples uses a custom cell style</a>. As with the renderer, each cell has the opportunity to alter itself with a custom function &#8211; here&#8217;s the one we use in the <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/countries.html">countries example</a>:</p>
<pre class="brush: jscript;">
new Ext.grid.PivotGrid({
    store     : myStore,
    aggregator: 'avg',
    measure   : 'height',

    viewConfig: {
        getCellCls: function(value) {
            if (value &lt; 20) {
                return 'expense-low';
            } else if (value &lt; 75) {
                return 'expense-medium';
            } else {
                return 'expense-high';
            }
        }
    },
    //the rest of the config
});
</pre>
<h2>Reconfiguring at runtime</h2>
<p>A lot of the power of PivotGrid is that it can be used by users of your application to summarize datasets any way they want. This is made possible by PivotGrid&#8217;s ability to reconfigure itself at runtime. We present one final example of a <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/reconfigurable.html">PivotGrid that can be reconfigured at runtime</a>. Here&#8217;s how we perform the reconfiguration:</p>
<pre class="brush: jscript;">
//the left axis can also be changed
pivot.topAxis.setDimensions([
    {dataIndex: 'city', direction: 'DESC'},
    {dataIndex: 'year', direction: 'ASC'}
]);

pivot.setMeasure('value');
pivot.setAggregator('avg');

pivot.view.refresh(true);
</pre>
<p>It&#8217;s easy to change the axes, dimension, aggregator and measure at any time and then refresh the data. The calculations are all performed client side so there is no need for another round-trip to the server when reconfiguring. The example linked above gives an example interface for updating a PivotGrid, though anything that can make the API calls above could be used.</p>
<p>I hope you enjoy the new components in this Ext JS 3.3 beta and look forward to comments and suggestions. Although we&#8217;re only at beta stage I think the additions are already quite robust so feel free to stress-test them.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2010/07/using-the-ext-js-pivotgrid.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Offline Apps with HTML5: A case study in Solitaire</title>
		<link>http://edspencer.net/2010/06/offline-apps-with-html5-a-case-study-in-solitaire.html</link>
		<comments>http://edspencer.net/2010/06/offline-apps-with-html5-a-case-study-in-solitaire.html#comments</comments>
		<pubDate>Mon, 21 Jun 2010 15:43:53 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[application cache]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[offline]]></category>
		<category><![CDATA[sencha]]></category>
		<category><![CDATA[web storage]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=445</guid>
		<description><![CDATA[<p>One of my contributions to the newly-launched <a href="http://www.sencha.com/products/touch/">Sencha Touch</a> mobile framework is the <a href="http://touchsolitaire.mobi/">Touch Solitaire</a> game. This is not the first time I have ventured into the dizzying excitement of Solitaire game development; you may remember the wonderful <a href="http://solitaire.edspencer.net/">Ext JS Solitaire</a> from 18 months ago. I&#8217;m sure you&#8217;ll agree that the new version is a small improvement.</p>
<p><a href="http://touchsolitaire.mobi"><div id="attachment_466" class="wp-caption alignleft" style="width: 670px"><img src="http://edspencer.net/wp-content/uploads/2010/06/solitaire.gif" alt="Touch Solitaire is beautiful and feels like a native app" title="Solitaire screenshot" width="660" height="495" class="size-full wp-image-466" /><p class="wp-caption-text">Touch Solitaire is beautiful and feels like a native app</p></div></a></p>
<p>Solitaire is a nice example of a fun application that can be written with Sencha Touch. It makes use of the provided Draggables and Droppables, CSS-based animations, the layout manager and the brand new data package. The great thing about a game like this though is that it can be run entirely offline. Obviously this is simple with a native application, but what about a web app? Our goal is not just having the game able to run offline, but to save your game state locally too.</p>
<p>The answer comes in two parts:</p>
<h2>Web Storage and the Sencha data package</h2>
<p>HTML5 provides a brand new API called Web Storage for storing data locally. You can read all about it on my <a href="http://www.sencha.com/blog/2010/05/27/the-html5-family-web-storage/">Web Storage post on Sencha&#8217;s blog</a> but the summary is that you can store string data locally in the browser and retrieve it later, even if the browser or the user&#8217;s computer had been restarted in the meantime.</p>
<p>The crucial part of the sentence above is that we can only store string data. In the case of a game of Solitaire we need to store data on the elapsed time and number of moves as well as the location and status of each card. This doesn&#8217;t sound like the kind of data we want to manually encode into a string, so thankfully the data package comes to the rescue.</p>
<p>The Sencha Touch data package is a complete rewrite of the package that has been so successful in powering Ext JS 3.x. It shares many of the same philosophies and adds the learning we have gained from developing Ext JS 3.x over the past year. One of the new capabilities it offers us is a <a href="http://www.sencha.com/deploy/touch/docs/?class=Ext.data.LocalStorageProxy">Local Storage proxy</a>, which automatically marshalls your model data into local storage and transparently restores it when you need it.</p>
<p>Using the new proxy is simple &#8211; all we need to do is set up a new Store, specifying the Proxy and the Model that will be saved to it. Models are the spiritual successor to Ext JS 3.x&#8217;s Records. Now whenever we add, remove or update model instances in the store they are automatically saved to localStorage for us. Loading the store again is equally easy:</p>
<pre class="brush: jscript;">
//set the store up
var gameStore = new Ext.data.Store({
    proxy: new Ext.data.LocalStorageProxy({
        id: 'solitaire-games'
    }),
    model: 'Game'
});

//saves all outstanding modifications, deletions or creations to localStorage
gameStore.sync();

//load our saved games
gameStore.read({
    scope: this,
    callback: function(records) {
        //code to load the first record
    }
});
</pre>
<p>And just like that we can save and restore games with Web Storage. We can visit our app&#8217;s webpage and start a game then come back later and find it automatically restored. But we still can&#8217;t play offline, for that we need the application cache.</p>
<h2>The HTML5 Application Cache Manifest</h2>
<p>The application cache is one of the best features of HTML5. It provides a simple (though sometimes frustrating) way of telling the browser about all of the files your application relies on so that it can download them all ready for offline use. All you have to do is create what&#8217;s known as a manifest file which lists all of the files the application needs &#8211; the Solitaire manifest looks like this:</p>
<pre class="brush: plain;">
CACHE MANIFEST
#rev49

resources/icon.png
resources/loading.png

resources/themes/wood/board.jpg
resources/themes/wood/cards.png

resources/css/ext-touch.css
resources/solitaire-notheme.css
resources/themes/wood/wood.css
resources/themes/metal/metal.css

ext-touch-debug.js
solitaire-all-debug.js
</pre>
<p>We tell the browser about the manifest file by pointing to it in the <html> tag&#8217;s <em>manifest</em> atttibute. When the browser finds this file it downloads each of the listed assets so that they are ready for offline consumption. Note that it does not automatically include them on the page, you still need to do that yourself via the usual link and script tags. Here&#8217;s a snippet of the Solitaire index.html file:</p>
<pre class="brush: xml;">
&lt;!doctype html&gt;
&lt;html manifest=&quot;solitaire.manifest&quot;&gt;
    &lt;head&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
        &lt;title&gt;Solitaire&lt;/title&gt;

        &lt;link rel=&quot;stylesheet&quot; href=&quot;resources/css/ext-touch.css&quot; type=&quot;text/css&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;resources/solitaire-notheme.css&quot; type=&quot;text/css&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;resources/themes/wood/wood.css&quot; type=&quot;text/css&quot;&gt;

        &lt;script type=&quot;text/javascript&quot; src=&quot;ext-touch-debug.js&quot;&gt;&lt;/script&gt;
        &lt;script type=&quot;text/javascript&quot; src=&quot;solitaire-all-debug.js&quot;&gt;&lt;/script&gt;
</pre>
<p>Note the manifest file definition in the html element at the top, and the fact that we still include our page resources the normal way. It sounds easy, but without a little setup first it can be a very frustrating experience. Usually your browser will try to cache as many files as possible, including the manifest file itself &#8211; we don&#8217;t want this. As soon as your browser has a long-term cache of the manifest file it is extremely difficult to update your application &#8211; all of the files are already offline and won&#8217;t be updated, and the browser won&#8217;t even ask the server for an updated manifest file.</p>
<p>Preventing this behaviour turns out to be fairly easy, and the solution in its simplest form comes in the shape of a .htaccess file with contents like the following:</p>
<pre class="brush: plain;">
&lt;Files solitaire.manifest&gt;
    ExpiresActive On
    ExpiresDefault &quot;access&quot;
&lt;/Files&gt;
</pre>
<p>This directs Apache to tell the browser not to cache the manifest file at all, instead requesting the file from the server on every page load. Note that if the device is currently offline it will use the last manifest file it received.</p>
<p>This is half the battle won, but let&#8217;s say you change one of your application files and reload &#8211; you&#8217;ll find nothing happened. This is because when your browser asked the server for the manifest file it actually asked if the file had changed or not. As the manifest itself wasn&#8217;t updated, the server responds with a 304 (Not Modified) and your browser keeps the old file.</p>
<p>To make the browser pick up on the change to the application file you need to update the manifest file itself. This is where the mysterious &#8220;#rev49&#8243; comes in on the manifest example file above. This is a suggestion from the <a href="http://diveintohtml5.org/offline.html">excellent diveintohtml5 article</a> on the subject &#8211; whenever you change any application files just bump up the revision number in the manifest file and your browser will know to download the updated files.</p>
<p>One final detail is that your Apache server probably isn&#8217;t set up to server manifest files with the correct mime type, so be sure to add the following line to your Apache config and restart the server:</p>
<pre class="brush: plain;">
AddType text/cache-manifest .manifest
</pre>
<h2>Wrapping it up</h2>
<p>Offline access is a big deal for mobile apps and Sencha Touch makes them much easier to write. The benefit is not so much that the apps can run without an internet connection (many modern touch devices have a near-permanent connection to the internet already), but that web apps can now be treated as first-class citizens alongside native apps.</p>
<p>The fact that many devices allow your users to save your app to their home screen and load it as though it were native is an important step &#8211; you keep all of the advantages of web app deployment while gaining some of the benefits of native apps. As more and more native hardware APIs become available to web apps their importance will only grow.</p>
<p>If you want to check out Solitaire&#8217;s offline support for yourself <a href="http://touchsolitaire.mobi/app/">visit the application&#8217;s site</a> and save it to your iPad&#8217;s home page. Try turning on airplane mode and loading the app and see how it behaves as though it were native. If you don&#8217;t have an iPad, you can load the app in up-to-date versions of Chrome or Safari and get a similar experience.</p>
]]></description>
			<content:encoded><![CDATA[<p>One of my contributions to the newly-launched <a href="http://www.sencha.com/products/touch/">Sencha Touch</a> mobile framework is the <a href="http://touchsolitaire.mobi/">Touch Solitaire</a> game. This is not the first time I have ventured into the dizzying excitement of Solitaire game development; you may remember the wonderful <a href="http://solitaire.edspencer.net/">Ext JS Solitaire</a> from 18 months ago. I&#8217;m sure you&#8217;ll agree that the new version is a small improvement.</p>
<p><a href="http://touchsolitaire.mobi"><div id="attachment_466" class="wp-caption alignleft" style="width: 670px"><img src="http://edspencer.net/wp-content/uploads/2010/06/solitaire.gif" alt="Touch Solitaire is beautiful and feels like a native app" title="Solitaire screenshot" width="660" height="495" class="size-full wp-image-466" /><p class="wp-caption-text">Touch Solitaire is beautiful and feels like a native app</p></div></a></p>
<p>Solitaire is a nice example of a fun application that can be written with Sencha Touch. It makes use of the provided Draggables and Droppables, CSS-based animations, the layout manager and the brand new data package. The great thing about a game like this though is that it can be run entirely offline. Obviously this is simple with a native application, but what about a web app? Our goal is not just having the game able to run offline, but to save your game state locally too.</p>
<p>The answer comes in two parts:</p>
<h2>Web Storage and the Sencha data package</h2>
<p>HTML5 provides a brand new API called Web Storage for storing data locally. You can read all about it on my <a href="http://www.sencha.com/blog/2010/05/27/the-html5-family-web-storage/">Web Storage post on Sencha&#8217;s blog</a> but the summary is that you can store string data locally in the browser and retrieve it later, even if the browser or the user&#8217;s computer had been restarted in the meantime.</p>
<p>The crucial part of the sentence above is that we can only store string data. In the case of a game of Solitaire we need to store data on the elapsed time and number of moves as well as the location and status of each card. This doesn&#8217;t sound like the kind of data we want to manually encode into a string, so thankfully the data package comes to the rescue.</p>
<p>The Sencha Touch data package is a complete rewrite of the package that has been so successful in powering Ext JS 3.x. It shares many of the same philosophies and adds the learning we have gained from developing Ext JS 3.x over the past year. One of the new capabilities it offers us is a <a href="http://www.sencha.com/deploy/touch/docs/?class=Ext.data.LocalStorageProxy">Local Storage proxy</a>, which automatically marshalls your model data into local storage and transparently restores it when you need it.</p>
<p>Using the new proxy is simple &#8211; all we need to do is set up a new Store, specifying the Proxy and the Model that will be saved to it. Models are the spiritual successor to Ext JS 3.x&#8217;s Records. Now whenever we add, remove or update model instances in the store they are automatically saved to localStorage for us. Loading the store again is equally easy:</p>
<pre class="brush: jscript;">
//set the store up
var gameStore = new Ext.data.Store({
    proxy: new Ext.data.LocalStorageProxy({
        id: 'solitaire-games'
    }),
    model: 'Game'
});

//saves all outstanding modifications, deletions or creations to localStorage
gameStore.sync();

//load our saved games
gameStore.read({
    scope: this,
    callback: function(records) {
        //code to load the first record
    }
});
</pre>
<p>And just like that we can save and restore games with Web Storage. We can visit our app&#8217;s webpage and start a game then come back later and find it automatically restored. But we still can&#8217;t play offline, for that we need the application cache.</p>
<h2>The HTML5 Application Cache Manifest</h2>
<p>The application cache is one of the best features of HTML5. It provides a simple (though sometimes frustrating) way of telling the browser about all of the files your application relies on so that it can download them all ready for offline use. All you have to do is create what&#8217;s known as a manifest file which lists all of the files the application needs &#8211; the Solitaire manifest looks like this:</p>
<pre class="brush: plain;">
CACHE MANIFEST
#rev49

resources/icon.png
resources/loading.png

resources/themes/wood/board.jpg
resources/themes/wood/cards.png

resources/css/ext-touch.css
resources/solitaire-notheme.css
resources/themes/wood/wood.css
resources/themes/metal/metal.css

ext-touch-debug.js
solitaire-all-debug.js
</pre>
<p>We tell the browser about the manifest file by pointing to it in the <html> tag&#8217;s <em>manifest</em> atttibute. When the browser finds this file it downloads each of the listed assets so that they are ready for offline consumption. Note that it does not automatically include them on the page, you still need to do that yourself via the usual link and script tags. Here&#8217;s a snippet of the Solitaire index.html file:</p>
<pre class="brush: xml;">
&lt;!doctype html&gt;
&lt;html manifest=&quot;solitaire.manifest&quot;&gt;
    &lt;head&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
        &lt;title&gt;Solitaire&lt;/title&gt;

        &lt;link rel=&quot;stylesheet&quot; href=&quot;resources/css/ext-touch.css&quot; type=&quot;text/css&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;resources/solitaire-notheme.css&quot; type=&quot;text/css&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;resources/themes/wood/wood.css&quot; type=&quot;text/css&quot;&gt;

        &lt;script type=&quot;text/javascript&quot; src=&quot;ext-touch-debug.js&quot;&gt;&lt;/script&gt;
        &lt;script type=&quot;text/javascript&quot; src=&quot;solitaire-all-debug.js&quot;&gt;&lt;/script&gt;
</pre>
<p>Note the manifest file definition in the html element at the top, and the fact that we still include our page resources the normal way. It sounds easy, but without a little setup first it can be a very frustrating experience. Usually your browser will try to cache as many files as possible, including the manifest file itself &#8211; we don&#8217;t want this. As soon as your browser has a long-term cache of the manifest file it is extremely difficult to update your application &#8211; all of the files are already offline and won&#8217;t be updated, and the browser won&#8217;t even ask the server for an updated manifest file.</p>
<p>Preventing this behaviour turns out to be fairly easy, and the solution in its simplest form comes in the shape of a .htaccess file with contents like the following:</p>
<pre class="brush: plain;">
&lt;Files solitaire.manifest&gt;
    ExpiresActive On
    ExpiresDefault &quot;access&quot;
&lt;/Files&gt;
</pre>
<p>This directs Apache to tell the browser not to cache the manifest file at all, instead requesting the file from the server on every page load. Note that if the device is currently offline it will use the last manifest file it received.</p>
<p>This is half the battle won, but let&#8217;s say you change one of your application files and reload &#8211; you&#8217;ll find nothing happened. This is because when your browser asked the server for the manifest file it actually asked if the file had changed or not. As the manifest itself wasn&#8217;t updated, the server responds with a 304 (Not Modified) and your browser keeps the old file.</p>
<p>To make the browser pick up on the change to the application file you need to update the manifest file itself. This is where the mysterious &#8220;#rev49&#8243; comes in on the manifest example file above. This is a suggestion from the <a href="http://diveintohtml5.org/offline.html">excellent diveintohtml5 article</a> on the subject &#8211; whenever you change any application files just bump up the revision number in the manifest file and your browser will know to download the updated files.</p>
<p>One final detail is that your Apache server probably isn&#8217;t set up to server manifest files with the correct mime type, so be sure to add the following line to your Apache config and restart the server:</p>
<pre class="brush: plain;">
AddType text/cache-manifest .manifest
</pre>
<h2>Wrapping it up</h2>
<p>Offline access is a big deal for mobile apps and Sencha Touch makes them much easier to write. The benefit is not so much that the apps can run without an internet connection (many modern touch devices have a near-permanent connection to the internet already), but that web apps can now be treated as first-class citizens alongside native apps.</p>
<p>The fact that many devices allow your users to save your app to their home screen and load it as though it were native is an important step &#8211; you keep all of the advantages of web app deployment while gaining some of the benefits of native apps. As more and more native hardware APIs become available to web apps their importance will only grow.</p>
<p>If you want to check out Solitaire&#8217;s offline support for yourself <a href="http://touchsolitaire.mobi/app/">visit the application&#8217;s site</a> and save it to your iPad&#8217;s home page. Try turning on airplane mode and loading the app and see how it behaves as though it were native. If you don&#8217;t have an iPad, you can load the app in up-to-date versions of Chrome or Safari and get a similar experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2010/06/offline-apps-with-html5-a-case-study-in-solitaire.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>2010: The year Ext JS takes over</title>
		<link>http://edspencer.net/2010/01/2010-the-year-ext-js-takes-over.html</link>
		<comments>http://edspencer.net/2010/01/2010-the-year-ext-js-takes-over.html#comments</comments>
		<pubDate>Wed, 13 Jan 2010 17:12:07 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[extjs]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=365</guid>
		<description><![CDATA[<p>On January 1st 2010 I officially joined <a href="http://extjs.com">Ext JS</a> to take over the role of lead developer.  <a href="http://edspencer.net/category/extjs">After living and breathing Ext for the last 3 years</a> I am delighted to have joined the company itself.  Ext JS has lead the way in developing rich client side applications since the very first release; this is a tradition we will continue and build upon.  </p>
<p>2010 is going to be an extremely exciting year for Ext JS.  A new focus is being placed on helping developers create their applications much more quickly, with the help of <a href="http://www.extjs.com/blog/2009/10/08/ext-js-designer-preview/">advanced creation tools</a> and a standardised application architecture right out of the box.</p>
<p>We will continue the <a href="http://www.extjs.com/blog/2009/12/17/ext-js-3-1-massive-memory-improvements-treegrid-and-more%e2%80%a6/">performance improvements started in 3.1</a> to make sure that Ext applications really fly.  Ext JS 3.2 will be the fastest, most stable version ever released.</p>
<p>2010 is also the year that Ext JS becomes much easier to learn.  With a completely reinvented learning section, Ext will no longer take months to learn and understand &#8211; even our API documentation will get a facelift.</p>
<p>The upcoming Marketplace will be the perfect venue to find and share new, high quality components created by our awesome developer community.  Think of the Marketplace as the App Store for Ext JS &#8211; full of great offerings that are easy to drop in to any application.</p>
<h2>Calling all able-minded Ext JS developers</h2>
<p>Ext JS is already the best JavaScript library in the world for creating rich, desktop-quality applications on the web.  If you want to help us make it even better, I want to hear from you.</p>
<p>As well as creating new components and improving our application support, we need people to help us maintain the quality and stability of what we already have.  If you&#8217;re intimate with Ext and think you have what it takes to get involved, <a href="http://www.extjs.com/forum/member.php?u=59955">drop me a PM and introduce yourself</a>.</p>
]]></description>
			<content:encoded><![CDATA[<p>On January 1st 2010 I officially joined <a href="http://extjs.com">Ext JS</a> to take over the role of lead developer.  <a href="http://edspencer.net/category/extjs">After living and breathing Ext for the last 3 years</a> I am delighted to have joined the company itself.  Ext JS has lead the way in developing rich client side applications since the very first release; this is a tradition we will continue and build upon.  </p>
<p>2010 is going to be an extremely exciting year for Ext JS.  A new focus is being placed on helping developers create their applications much more quickly, with the help of <a href="http://www.extjs.com/blog/2009/10/08/ext-js-designer-preview/">advanced creation tools</a> and a standardised application architecture right out of the box.</p>
<p>We will continue the <a href="http://www.extjs.com/blog/2009/12/17/ext-js-3-1-massive-memory-improvements-treegrid-and-more%e2%80%a6/">performance improvements started in 3.1</a> to make sure that Ext applications really fly.  Ext JS 3.2 will be the fastest, most stable version ever released.</p>
<p>2010 is also the year that Ext JS becomes much easier to learn.  With a completely reinvented learning section, Ext will no longer take months to learn and understand &#8211; even our API documentation will get a facelift.</p>
<p>The upcoming Marketplace will be the perfect venue to find and share new, high quality components created by our awesome developer community.  Think of the Marketplace as the App Store for Ext JS &#8211; full of great offerings that are easy to drop in to any application.</p>
<h2>Calling all able-minded Ext JS developers</h2>
<p>Ext JS is already the best JavaScript library in the world for creating rich, desktop-quality applications on the web.  If you want to help us make it even better, I want to hear from you.</p>
<p>As well as creating new components and improving our application support, we need people to help us maintain the quality and stability of what we already have.  If you&#8217;re intimate with Ext and think you have what it takes to get involved, <a href="http://www.extjs.com/forum/member.php?u=59955">drop me a PM and introduce yourself</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2010/01/2010-the-year-ext-js-takes-over.html/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Ext.ux.Exporter &#8211; export any Grid to Excel or CSV</title>
		<link>http://edspencer.net/2009/11/ext-ux-exporter-export-any-grid-to-excel-or-csv.html</link>
		<comments>http://edspencer.net/2009/11/ext-ux-exporter-export-any-grid-to-excel-or-csv.html#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:32:33 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[grid]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=342</guid>
		<description><![CDATA[<p>Sometimes we want to print things, like grids or trees.  The <a href="http://edspencer.net/2009/07/extuxprinter-printing-for-any-ext.html">Ext JS printing plugin</a> is pretty good for that.  But what if we want to export them instead? Enter <a href="http://github.com/edspencer/Ext.ux.Exporter">Ext.ux.Exporter</a>.</p>
<p>Ext.ux.Exporter allows any store-based component (such as grids) to be exported, <b>locally</b>, to Excel or any other format.  It does not require any server side programming &#8211; the export document is generated on the fly, entirely in JavaScript.</p>
<p>The extension serves as a base for exporting any kind of data, but comes bundled with a .xls export formatter suitable for exporting any Grid straight to Excel.  Here&#8217;s how to do that:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  store: someStore,
  tbar : [
    {
      xtype: 'exportbutton',
      store: someStore
    }
  ],
  //your normal grid config goes here
});
</pre>
<p>Clicking the Download button in the top toolbar iterates over the data in the store and creates an Excel file locally, before Base64 encoding it and redirecting the browser via a data url.  If you have Excel or a similar program installed your browser should ask you to save the file or open it with Excel.</p>
<p>I put together a quick example of the plugin in action inside the repository, just <a href="http://github.com/edspencer/Ext.ux.Exporter">clone</a> or <a href="http://github.com/edspencer/Ext.ux.Exporter/zipball/master">download the code</a> and drag the examples/index.html file into your browser to run it.</p>
<p>The Exporter will work with any store or store-based component.  It also allows export to any format &#8211; for example CSV or PDF.  Although the Excel Formatter is probably the most useful, implementing a CSV or other Formatter should be trivial &#8211; check out the Excel Formatter example in the <a href="http://github.com/edspencer/Ext.ux.Exporter/tree/master/ExcelFormatter/">ExcelFormatter</a> directory.</p>
]]></description>
			<content:encoded><![CDATA[<p>Sometimes we want to print things, like grids or trees.  The <a href="http://edspencer.net/2009/07/extuxprinter-printing-for-any-ext.html">Ext JS printing plugin</a> is pretty good for that.  But what if we want to export them instead? Enter <a href="http://github.com/edspencer/Ext.ux.Exporter">Ext.ux.Exporter</a>.</p>
<p>Ext.ux.Exporter allows any store-based component (such as grids) to be exported, <b>locally</b>, to Excel or any other format.  It does not require any server side programming &#8211; the export document is generated on the fly, entirely in JavaScript.</p>
<p>The extension serves as a base for exporting any kind of data, but comes bundled with a .xls export formatter suitable for exporting any Grid straight to Excel.  Here&#8217;s how to do that:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  store: someStore,
  tbar : [
    {
      xtype: 'exportbutton',
      store: someStore
    }
  ],
  //your normal grid config goes here
});
</pre>
<p>Clicking the Download button in the top toolbar iterates over the data in the store and creates an Excel file locally, before Base64 encoding it and redirecting the browser via a data url.  If you have Excel or a similar program installed your browser should ask you to save the file or open it with Excel.</p>
<p>I put together a quick example of the plugin in action inside the repository, just <a href="http://github.com/edspencer/Ext.ux.Exporter">clone</a> or <a href="http://github.com/edspencer/Ext.ux.Exporter/zipball/master">download the code</a> and drag the examples/index.html file into your browser to run it.</p>
<p>The Exporter will work with any store or store-based component.  It also allows export to any format &#8211; for example CSV or PDF.  Although the Excel Formatter is probably the most useful, implementing a CSV or other Formatter should be trivial &#8211; check out the Excel Formatter example in the <a href="http://github.com/edspencer/Ext.ux.Exporter/tree/master/ExcelFormatter/">ExcelFormatter</a> directory.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/11/ext-ux-exporter-export-any-grid-to-excel-or-csv.html/feed</wfw:commentRss>
		<slash:comments>80</slash:comments>
		</item>
		<item>
		<title>Ext.ux.layout.FillContainer</title>
		<link>http://edspencer.net/2009/09/ext-ux-layout-fillcontainer.html</link>
		<comments>http://edspencer.net/2009/09/ext-ux-layout-fillcontainer.html#comments</comments>
		<pubDate>Mon, 28 Sep 2009 13:46:27 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[layouts]]></category>

		<guid isPermaLink="false">http://edspencer.net/?p=200</guid>
		<description><![CDATA[<p>One of the pages on the Ext JS app I&#8217;m currently working on has a form with a grid underneath.  The page exists as a tab inside an Ext.TabPanel, and uses the <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.layout.BorderLayout">border layout</a>, with the form as the &#8216;north&#8217; component and the grid as &#8216;center&#8217;.</p>
<p>The trouble with this is that the grid shrinks down to an unusable size when the browser window is too small, ending up like this:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/20c85b5c-c376-4129-a742-cd46328375d3/00000040.png" alt="Border layout" width="680" /></p>
<p>We could alternatively use a basic container layout, but this limits us to a fixed height for the grid, meaning we waste space at the bottom:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/92ae47ec-1e5e-454a-b127-fa67eef09abd/00000039.png" alt="Container layout" width="680" /></p>
<p>Enter the imaginatively named FillContainer:</p>
<pre class="brush: jscript;">
new Ext.Panel({
  autoScroll: true,
  layout: 'fillcontainer',
  items : [
    {
      html  : 'Pretend this is a form',
      height: 400
    },
    {
      html         : 'And this is the grid',
      minHeight    : 250,
      fillContainer: true
    }
  ]
});
</pre>
<p>If our containing panel shrinks to less than 650px in height, the grid will be automatically sized to 250px and a vertical scrollbar will appear on the panel, like this:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/b3ab92bb-57bf-4a92-b52c-84ff499e5f78/00000037.png" alt="Fill Container with scroll bar" width="680" /></p>
<p>If the panel&#8217;s height increases to, say, 900px, the grid gets resized to 500px high.  This way we use the space when it&#8217;s available, while maintaining a usable interface when height is limited:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/f67ba4a0-7f1b-4a3f-bd1c-ebb89319e34b/00000038.png" alt="Fill Container with stretched item" width="680" /></p>
<p>Here&#8217;s the code that makes it work:</p>
<pre class="brush: jscript;">
Ext.ns('Ext.ux.layout');

/**
 * @class Ext.ux.layout.FillContainerLayout
 * @extends Ext.layout.ContainerLayout
 * @author Ed Spencer (http://edspencer.net)
 * Extended version of container layout which expands a given child item to the
 * full height of the container, honouring the item's minHeight property
 */
Ext.ux.layout.FillContainerLayout = Ext.extend(Ext.layout.ContainerLayout, {
  monitorResize: true,

  /**
   * After rendering each item, resize the one with fillContainer == true
   */
  onLayout: function(ct, target) {
    Ext.ux.layout.FillContainerLayout.superclass.onLayout.apply(this, arguments);

    var ctHeight    = ct.getHeight(),
        itemsHeight = 0,
        expandItem;

    ct.items.each(function(item) {
      if (item.fillContainer === true) {
        expandItem = item;
      } else {
        itemsHeight += item.getHeight();
      }
    });

    //set the expand item's height to fill the container
    if (expandItem != undefined &amp;&amp; ctHeight &gt; itemsHeight) {
      var newHeight = ctHeight - itemsHeight;

      expandItem.setHeight(Math.max(newHeight, expandItem.minHeight));
    }
  }
});

Ext.Container.LAYOUTS['fillcontainer'] = Ext.ux.layout.FillContainerLayout;
</pre>
<p>As we&#8217;re just extending the default container layout, your items will be rendered in the order you specify them.  The expanding item doesn&#8217;t have to be the last one &#8211; we could equally have set fillContainer and minHeight on the form to expand that instead of the grid.</p>
]]></description>
			<content:encoded><![CDATA[<p>One of the pages on the Ext JS app I&#8217;m currently working on has a form with a grid underneath.  The page exists as a tab inside an Ext.TabPanel, and uses the <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.layout.BorderLayout">border layout</a>, with the form as the &#8216;north&#8217; component and the grid as &#8216;center&#8217;.</p>
<p>The trouble with this is that the grid shrinks down to an unusable size when the browser window is too small, ending up like this:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/20c85b5c-c376-4129-a742-cd46328375d3/00000040.png" alt="Border layout" width="680" /></p>
<p>We could alternatively use a basic container layout, but this limits us to a fixed height for the grid, meaning we waste space at the bottom:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/92ae47ec-1e5e-454a-b127-fa67eef09abd/00000039.png" alt="Container layout" width="680" /></p>
<p>Enter the imaginatively named FillContainer:</p>
<pre class="brush: jscript;">
new Ext.Panel({
  autoScroll: true,
  layout: 'fillcontainer',
  items : [
    {
      html  : 'Pretend this is a form',
      height: 400
    },
    {
      html         : 'And this is the grid',
      minHeight    : 250,
      fillContainer: true
    }
  ]
});
</pre>
<p>If our containing panel shrinks to less than 650px in height, the grid will be automatically sized to 250px and a vertical scrollbar will appear on the panel, like this:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/b3ab92bb-57bf-4a92-b52c-84ff499e5f78/00000037.png" alt="Fill Container with scroll bar" width="680" /></p>
<p>If the panel&#8217;s height increases to, say, 900px, the grid gets resized to 500px high.  This way we use the space when it&#8217;s available, while maintaining a usable interface when height is limited:</p>
<p><img src="http://content.screencast.com/users/edspencer/folders/Jing/media/f67ba4a0-7f1b-4a3f-bd1c-ebb89319e34b/00000038.png" alt="Fill Container with stretched item" width="680" /></p>
<p>Here&#8217;s the code that makes it work:</p>
<pre class="brush: jscript;">
Ext.ns('Ext.ux.layout');

/**
 * @class Ext.ux.layout.FillContainerLayout
 * @extends Ext.layout.ContainerLayout
 * @author Ed Spencer (http://edspencer.net)
 * Extended version of container layout which expands a given child item to the
 * full height of the container, honouring the item's minHeight property
 */
Ext.ux.layout.FillContainerLayout = Ext.extend(Ext.layout.ContainerLayout, {
  monitorResize: true,

  /**
   * After rendering each item, resize the one with fillContainer == true
   */
  onLayout: function(ct, target) {
    Ext.ux.layout.FillContainerLayout.superclass.onLayout.apply(this, arguments);

    var ctHeight    = ct.getHeight(),
        itemsHeight = 0,
        expandItem;

    ct.items.each(function(item) {
      if (item.fillContainer === true) {
        expandItem = item;
      } else {
        itemsHeight += item.getHeight();
      }
    });

    //set the expand item's height to fill the container
    if (expandItem != undefined &amp;&amp; ctHeight &gt; itemsHeight) {
      var newHeight = ctHeight - itemsHeight;

      expandItem.setHeight(Math.max(newHeight, expandItem.minHeight));
    }
  }
});

Ext.Container.LAYOUTS['fillcontainer'] = Ext.ux.layout.FillContainerLayout;
</pre>
<p>As we&#8217;re just extending the default container layout, your items will be rendered in the order you specify them.  The expanding item doesn&#8217;t have to be the last one &#8211; we could equally have set fillContainer and minHeight on the form to expand that instead of the grid.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/09/ext-ux-layout-fillcontainer.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using the ExtJS Row Editor</title>
		<link>http://edspencer.net/2009/09/using-the-extjs-row-editor.html</link>
		<comments>http://edspencer.net/2009/09/using-the-extjs-row-editor.html#comments</comments>
		<pubDate>Wed, 16 Sep 2009 14:25:47 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[Misc]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[roweditor]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=41</guid>
		<description><![CDATA[<p>The <a href="http://www.extjs.com/deploy/dev/examples/grid/row-editor.html">RowEditor plugin</a> was recently added to the <a href="http://www.extjs.com/deploy/dev/examples/">ExtJS examples page</a>.  It works a lot like a normal Grid Editor, except you can edit several fields on a given row at once before saving.</p>
<p>This neatly solves the problem of adding a new row to an editor grid, entering data into the first field and finding it save itself straight away, which is rarely desired.  In this fashion we can provide full CRUD for simple models in a single page.</p>
<h2>Installation</h2>
<p>You&#8217;ll need to get a copy of the javascript, css and images from the server.  This is a bit of a pain.  If you still have the <a href="http://www.extjs.com/products/extjs/download.php">ExtJS SDK</a> around you can find these in the examples folder, if not you can get each file as follows:</p>
<p>Grab the plugin JS file below and put it where you usually put your .js files:<br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/RowEditor.js">http://www.extjs.com/deploy/dev/examples/ux/RowEditor.js</a></p>
<p>This needs to go with your other stylesheets, usually in a directory called &#8216;css&#8217;:<br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/css/RowEditor.css">http://www.extjs.com/deploy/dev/examples/ux/css/RowEditor.css</a></p>
<p>Download these two images and put them into your existing &#8216;images&#8217; folder (the same place the other ExtJS images live):<br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-bg.gif">http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-bg.gif</a><br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-btns.gif">http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-btns.gif</a></p>
<p>Include the .js and .css files on your page and you should be ready to go.</p>
<h2>Usage</h2>
<p>RowEditor is a normal grid plugin, so you&#8217;ll need to instantiate it and add to your grid&#8217;s &#8216;plugins&#8217; property.  You also need to define what type of Editor is available (if any) on each column:</p>
<pre class="brush: jscript;">
var editor = new Ext.ux.grid.RowEditor();

var grid = new Ext.grid.GridPanel({
  plugins: [editor],
  columns: [
    {
      header   : 'User Name',
      dataIndex: 'name',
      editor   : new Ext.form.TextField()
    },
    {
      header   : 'Email',
      dataIndex: 'email',
      editor   : new Ext.form.TextField()
    }
  ]
  ... the rest of your grid config here
});
</pre>
<p>RowEditor defines a few events, the most useful one being &#8216;afteredit&#8217;. Its signature looks like this:</p>
<pre class="brush: jscript;">
/**
 * @event afteredit
 * Fired after a row is edited and passes validation.  This event is fired
 * after the store's update event is fired with this edit.
 * @param {Ext.ux.grid.RowEditor} roweditor This object
 * @param {Object} changes Object with changes made to the record.
 * @param {Ext.data.Record} r The Record that was edited.
 * @param {Number} rowIndex The rowIndex of the row just edited
 */
'afteredit'
</pre>
<p>All you need to do is listen to that event on your RowEditor and save your model object appropriately.  First though, we&#8217;ll define the Ext.data.Record that we&#8217;re using in this grid&#8217;s store:</p>
<pre class="brush: jscript;">
var User = Ext.data.Record.create([
  {name: 'user_id', type: 'int'},
  {name: 'name',    type: 'string'},
  {name: 'email',   type: 'string'}
]);
</pre>
<p>And now the afteredit listener itself</p>
<pre class="brush: jscript;">
editor.on({
  scope: this,
  afteredit: function(roweditor, changes, record, rowIndex) {
    //your save logic here - might look something like this:
    Ext.Ajax.request({
      url   : record.phantom ? '/users' : '/users/' + record.get('user_id'),
      method: record.phantom ? 'POST'   : 'PUT',
      params: changes,
      success: function() {
        //post-processing here - this might include reloading the grid if there are calculated fields
      }
    });
  }
});
</pre>
<p>The code above simply takes the changes object (which is just key: value object with all the changed fields) and issues a request to your server backend.  &#8216;record.phantom&#8217; returns true if this record does not yet exist on the server &#8211; we use this information above to specify whether we&#8217;re POSTing to /users or PUTing to /users/123, in line with normal RESTful practices.</p>
<h2>Adding a new record</h2>
<p>The example above allows for editing an existing record, but how do we add a new one? Like this:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  //... the same config from above goes here,
  tbar: [
    {
      text   : &quot;Add User&quot;,
      handler: function() {
        //make a new empty User and stop any current editing
        var newUser = new User({});
        rowEditor.stopEditing();

        //add our new record as the first row, select it
        grid.store.insert(0, newUser);
        grid.getView().refresh();
        grid.getSelectionModel().selectRow(0);

        //start editing our new User
        rowEditor.startEditing(0);
      }
    }
  ]
});
</pre>
<p>Pretty simple stuff &#8211; we&#8217;ve just added a toolbar with a button which, when clicked, creates a new User record, inserts it at the top of the grid and focusses the RowEditor on it.</p>
<h2>Configuration Options</h2>
<p>Although not documented, the plugin has a few configuration options:</p>
<pre class="brush: jscript;">
var editor = new Ext.ux.grid.RowEditor({
  saveText  : &quot;My Save Button Text&quot;,
  cancelText: &quot;My Cancel Button Text&quot;,
  clicksToEdit: 1, //this changes from the default double-click activation to single click activation
  errorSummary: false //disables display of validation messages if the row is invalid
});
</pre>
<p>If you want to customise other elements of the RowEditor you probably can, but you&#8217;ll need to <a href="http://www.extjs.com/deploy/dev/examples/ux/RowEditor.js">take a look at the source</a> (it&#8217;s not scary).</p>
<h2>Final Thought</h2>
<p>RowEditor is a really nice component which can provide an intuitive interface and save you writing a lot of CRUD code.  It is best employed on grids with only a few columns &#8211; for models with lots of data fields you&#8217;re better off with a full FormPanel.</p>
<p>I&#8217;d be pretty happy to see this included in the default ExtJS distribution, as I find myself returning to it frequently.</p>
]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.extjs.com/deploy/dev/examples/grid/row-editor.html">RowEditor plugin</a> was recently added to the <a href="http://www.extjs.com/deploy/dev/examples/">ExtJS examples page</a>.  It works a lot like a normal Grid Editor, except you can edit several fields on a given row at once before saving.</p>
<p>This neatly solves the problem of adding a new row to an editor grid, entering data into the first field and finding it save itself straight away, which is rarely desired.  In this fashion we can provide full CRUD for simple models in a single page.</p>
<h2>Installation</h2>
<p>You&#8217;ll need to get a copy of the javascript, css and images from the server.  This is a bit of a pain.  If you still have the <a href="http://www.extjs.com/products/extjs/download.php">ExtJS SDK</a> around you can find these in the examples folder, if not you can get each file as follows:</p>
<p>Grab the plugin JS file below and put it where you usually put your .js files:<br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/RowEditor.js">http://www.extjs.com/deploy/dev/examples/ux/RowEditor.js</a></p>
<p>This needs to go with your other stylesheets, usually in a directory called &#8216;css&#8217;:<br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/css/RowEditor.css">http://www.extjs.com/deploy/dev/examples/ux/css/RowEditor.css</a></p>
<p>Download these two images and put them into your existing &#8216;images&#8217; folder (the same place the other ExtJS images live):<br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-bg.gif">http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-bg.gif</a><br />
<a href="http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-btns.gif">http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-btns.gif</a></p>
<p>Include the .js and .css files on your page and you should be ready to go.</p>
<h2>Usage</h2>
<p>RowEditor is a normal grid plugin, so you&#8217;ll need to instantiate it and add to your grid&#8217;s &#8216;plugins&#8217; property.  You also need to define what type of Editor is available (if any) on each column:</p>
<pre class="brush: jscript;">
var editor = new Ext.ux.grid.RowEditor();

var grid = new Ext.grid.GridPanel({
  plugins: [editor],
  columns: [
    {
      header   : 'User Name',
      dataIndex: 'name',
      editor   : new Ext.form.TextField()
    },
    {
      header   : 'Email',
      dataIndex: 'email',
      editor   : new Ext.form.TextField()
    }
  ]
  ... the rest of your grid config here
});
</pre>
<p>RowEditor defines a few events, the most useful one being &#8216;afteredit&#8217;. Its signature looks like this:</p>
<pre class="brush: jscript;">
/**
 * @event afteredit
 * Fired after a row is edited and passes validation.  This event is fired
 * after the store's update event is fired with this edit.
 * @param {Ext.ux.grid.RowEditor} roweditor This object
 * @param {Object} changes Object with changes made to the record.
 * @param {Ext.data.Record} r The Record that was edited.
 * @param {Number} rowIndex The rowIndex of the row just edited
 */
'afteredit'
</pre>
<p>All you need to do is listen to that event on your RowEditor and save your model object appropriately.  First though, we&#8217;ll define the Ext.data.Record that we&#8217;re using in this grid&#8217;s store:</p>
<pre class="brush: jscript;">
var User = Ext.data.Record.create([
  {name: 'user_id', type: 'int'},
  {name: 'name',    type: 'string'},
  {name: 'email',   type: 'string'}
]);
</pre>
<p>And now the afteredit listener itself</p>
<pre class="brush: jscript;">
editor.on({
  scope: this,
  afteredit: function(roweditor, changes, record, rowIndex) {
    //your save logic here - might look something like this:
    Ext.Ajax.request({
      url   : record.phantom ? '/users' : '/users/' + record.get('user_id'),
      method: record.phantom ? 'POST'   : 'PUT',
      params: changes,
      success: function() {
        //post-processing here - this might include reloading the grid if there are calculated fields
      }
    });
  }
});
</pre>
<p>The code above simply takes the changes object (which is just key: value object with all the changed fields) and issues a request to your server backend.  &#8216;record.phantom&#8217; returns true if this record does not yet exist on the server &#8211; we use this information above to specify whether we&#8217;re POSTing to /users or PUTing to /users/123, in line with normal RESTful practices.</p>
<h2>Adding a new record</h2>
<p>The example above allows for editing an existing record, but how do we add a new one? Like this:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  //... the same config from above goes here,
  tbar: [
    {
      text   : &quot;Add User&quot;,
      handler: function() {
        //make a new empty User and stop any current editing
        var newUser = new User({});
        rowEditor.stopEditing();

        //add our new record as the first row, select it
        grid.store.insert(0, newUser);
        grid.getView().refresh();
        grid.getSelectionModel().selectRow(0);

        //start editing our new User
        rowEditor.startEditing(0);
      }
    }
  ]
});
</pre>
<p>Pretty simple stuff &#8211; we&#8217;ve just added a toolbar with a button which, when clicked, creates a new User record, inserts it at the top of the grid and focusses the RowEditor on it.</p>
<h2>Configuration Options</h2>
<p>Although not documented, the plugin has a few configuration options:</p>
<pre class="brush: jscript;">
var editor = new Ext.ux.grid.RowEditor({
  saveText  : &quot;My Save Button Text&quot;,
  cancelText: &quot;My Cancel Button Text&quot;,
  clicksToEdit: 1, //this changes from the default double-click activation to single click activation
  errorSummary: false //disables display of validation messages if the row is invalid
});
</pre>
<p>If you want to customise other elements of the RowEditor you probably can, but you&#8217;ll need to <a href="http://www.extjs.com/deploy/dev/examples/ux/RowEditor.js">take a look at the source</a> (it&#8217;s not scary).</p>
<h2>Final Thought</h2>
<p>RowEditor is a really nice component which can provide an intuitive interface and save you writing a lot of CRUD code.  It is best employed on grids with only a few columns &#8211; for models with lots of data fields you&#8217;re better off with a full FormPanel.</p>
<p>I&#8217;d be pretty happy to see this included in the default ExtJS distribution, as I find myself returning to it frequently.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/09/using-the-extjs-row-editor.html/feed</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Ext.decorate</title>
		<link>http://edspencer.net/2009/08/extdecorate.html</link>
		<comments>http://edspencer.net/2009/08/extdecorate.html#comments</comments>
		<pubDate>Sun, 30 Aug 2009 18:06:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[extjs]]></category>
		<category><![CDATA[decorate]]></category>
		<category><![CDATA[overrides]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=40</guid>
		<description><![CDATA[<p>Sometimes you want to override one of the methods in ExtJS that return a configuration object &#8211; let&#8217;s use Ext.direct.RemotingProvider&#8217;s getCallData as an example, which looks like this:</p>
<pre class="brush: jscript;">
getCallData: function(t){
  return {
    action: t.action,
    method: t.method,
    data  : t.data,
    type  : 'rpc',
    tid   : t.tid
  };
}
</pre>
<p>Our aim is to add an &#8216;authentication_token&#8217; property to the returned object. You could provide the full config object again in an override, but usually you&#8217;re overriding to add, remove or change one or two properties and want to leave the rest unmolested. I used to find myself writing a lot of code with this pattern:</p>
<pre class="brush: jscript;">
//just adds an authentication token to the call data, for context see &lt;a href=&quot;http://www.extjs.com/forum/showthread.php?p=378912#post378912&quot;&gt;this forum thread&lt;/a&gt;
(function() {
  var originalGetCallData = Ext.direct.RemotingProvider.prototype.getCallData;

  Ext.override(Ext.direct.RemotingProvider, {
    getCallData: function(t) {
      var defaults = originalGetCallData.apply(this, arguments);

      return Ext.apply(defaults, {
        authenticity_token: '&lt;%= form_authenticity_token %&gt;'
      });
    }
  })
})();
</pre>
<p>All we&#8217;re really doing here is adding 1 config item &#8211; an authenticity_token, but it takes a lot of setup code to make that happen. Check out Ext.decorate:</p>
<pre class="brush: jscript;">
/**
 * @param {Function} klass The constructor function of the class to override (e.g. Ext.direct.RemotingProvider)
 * @param {String} property The name of the property the function to override is tied to on the klass' prototype
 * @param {Object} config An object that is Ext.apply'd to the usual return value of the function before returning
 */
Ext.decorate = function(klass, property, config) {
  var original = klass.prototype[property];
      override = {};

  override[property] = function() {
    var value = original.apply(this, arguments);

    return Ext.apply(value, config);
  };

  Ext.override(klass, override);
}
</pre>
<p>This lets us write the same override like this:</p>
<pre class="brush: jscript;">
Ext.decorate(Ext.direct.RemotingProvider, 'getCallData', {
  authenticity_token: '&lt;%= form_authenticity_token %&gt;'
});
</pre>
<p>Much nicer, we just tell it what we want with no need for unwieldy boilerplate code. This method doesn&#8217;t actually exist in Ext (though it would be good if something similar did), but you could define it yourself as above to keep such code nice and dry.</p>
]]></description>
			<content:encoded><![CDATA[<p>Sometimes you want to override one of the methods in ExtJS that return a configuration object &#8211; let&#8217;s use Ext.direct.RemotingProvider&#8217;s getCallData as an example, which looks like this:</p>
<pre class="brush: jscript;">
getCallData: function(t){
  return {
    action: t.action,
    method: t.method,
    data  : t.data,
    type  : 'rpc',
    tid   : t.tid
  };
}
</pre>
<p>Our aim is to add an &#8216;authentication_token&#8217; property to the returned object. You could provide the full config object again in an override, but usually you&#8217;re overriding to add, remove or change one or two properties and want to leave the rest unmolested. I used to find myself writing a lot of code with this pattern:</p>
<pre class="brush: jscript;">
//just adds an authentication token to the call data, for context see &lt;a href=&quot;http://www.extjs.com/forum/showthread.php?p=378912#post378912&quot;&gt;this forum thread&lt;/a&gt;
(function() {
  var originalGetCallData = Ext.direct.RemotingProvider.prototype.getCallData;

  Ext.override(Ext.direct.RemotingProvider, {
    getCallData: function(t) {
      var defaults = originalGetCallData.apply(this, arguments);

      return Ext.apply(defaults, {
        authenticity_token: '&lt;%= form_authenticity_token %&gt;'
      });
    }
  })
})();
</pre>
<p>All we&#8217;re really doing here is adding 1 config item &#8211; an authenticity_token, but it takes a lot of setup code to make that happen. Check out Ext.decorate:</p>
<pre class="brush: jscript;">
/**
 * @param {Function} klass The constructor function of the class to override (e.g. Ext.direct.RemotingProvider)
 * @param {String} property The name of the property the function to override is tied to on the klass' prototype
 * @param {Object} config An object that is Ext.apply'd to the usual return value of the function before returning
 */
Ext.decorate = function(klass, property, config) {
  var original = klass.prototype[property];
      override = {};

  override[property] = function() {
    var value = original.apply(this, arguments);

    return Ext.apply(value, config);
  };

  Ext.override(klass, override);
}
</pre>
<p>This lets us write the same override like this:</p>
<pre class="brush: jscript;">
Ext.decorate(Ext.direct.RemotingProvider, 'getCallData', {
  authenticity_token: '&lt;%= form_authenticity_token %&gt;'
});
</pre>
<p>Much nicer, we just tell it what we want with no need for unwieldy boilerplate code. This method doesn&#8217;t actually exist in Ext (though it would be good if something similar did), but you could define it yourself as above to keep such code nice and dry.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/08/extdecorate.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ext.ux.Printer &#8211; printing for any ExtJS Component</title>
		<link>http://edspencer.net/2009/07/extuxprinter-printing-for-any-ext.html</link>
		<comments>http://edspencer.net/2009/07/extuxprinter-printing-for-any-ext.html#comments</comments>
		<pubDate>Tue, 28 Jul 2009 21:02:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[extjs]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[print]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[tree]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=38</guid>
		<description><![CDATA[<p>After my <a href="http://edspencer.net/2009/07/printing-grids-with-ext-js.html">recent foray</a> into printing grids with ExtJS, I realised I needed to print some trees too. Seeing as some of the work was already done for the Grid example, it made sense to create a common API for printing any Ext.Component. And thus <a href="http://github.com/edspencer/Ext.ux.Printer">Ext.ux.Printer</a> was born:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({ // just a normal grid });
var tree = new Ext.tree.ColumnTree({ // just a normal column tree });

Ext.ux.Printer.print(grid);
Ext.ux.Printer.print(tree);
</pre>
<p>Each of the above opens a new window, renders some HTML (just a big table really), prints it and closes the window &#8211; all client side with no server side code required. Although trees and grids represent data quite differently internally, we can use the same API on Ext.ux.Printer to print them both.</p>
<p>Ext.ux.Printer uses Renderer classes to cope with a specific xtype, and adding Renderers for other components is easy. At the moment Ext.grid.GridPanel and Ext.tree.ColumnTree are supported out of the box, but let&#8217;s see how we&#8217;d add support for printing the contents of an Ext.Panel:</p>
<pre class="brush: jscript;">
/**
 * Prints the contents of an Ext.Panel
 */
Ext.ux.Printer.PanelRenderer = Ext.extend(Ext.ux.Printer.BaseRenderer, {

 /**
  * Generates the HTML fragment that will be rendered inside the &lt;html&gt; element of the printing window
  */
 generateBody: function(panel) {
   return String.format(&quot;&lt;div class='x-panel-print'&gt;{0}&lt;/div&gt;&quot;, panel.body.dom.innerHTML);
 }
});

Ext.ux.Printer.registerRenderer(&quot;panel&quot;, Ext.ux.Printer.PanelRenderer);
</pre>
<p>This is probably the simplest print renderer of all &#8211; we&#8217;re simply grabbing the HTML from inside a the panel&#8217;s body and returning it inside our own div.  We subclassed Ext.ux.Printer.BaseRenderer, and in this case all we needed to do was provide an implementation for generateBody. Whatever this function returns is rendered inside the &lt;body&gt; tag of the newly-opened printing window.</p>
<p>Notice that we registered this renderer for all components with the xtype of &#8216;panel&#8217;. Internally, Ext.ux.Printer examines the xtype chain of the component you pass it to print, and uses the first renderer that matches. As many Ext components inherit from Ext.Panel this can function as a catch-all renderer.</p>
<p>Here&#8217;s how we&#8217;d use our new renderer:</p>
<pre class="brush: jscript;">
var panel = new Ext.Panel({
  html: {
    tag: 'ul',
    chidren: [
      {tag: 'li', text: 'Item 1'},
      {tag: 'li', text: 'Item 2'},
      {tag: 'li', text: 'Item 3'}
    ]
  }
});

Ext.ux.Printer.print(panel);
</pre>
<p>Pretty straightforward. You can now print Ext.Panels the same way you&#8217;d print a Grid or a Tree. Take a look at the <a href="http://github.com/edspencer/Ext.ux.Printer/blob/master/renderers/GridPanel.js">Grid Renderer</a> and the <a href="http://github.com/edspencer/Ext.ux.Printer/blob/master/renderers/ColumnTree.js">ColumnTree Renderer</a> for examples of rendering more advanced components.</p>
<p>As usual, <a href="http://github.com/edspencer/Ext.ux.Printer">all of the Ext.ux.Printer source</a> is available on Github, and the README file there contains instructions for installation and usage.</p>
<p>Finally, when the printing window is opened it includes a stylesheet that it expects to find at &#8220;/stylesheets/print.css&#8221;. There is a default print.css stylesheet included with the extension to get you started, and you can specify where to find this stylesheet like this:</p>
<pre class="brush: jscript;">
Ext.ux.Printer.BaseRenderer.prototype.stylesheetPath = '/path/to/print/stylesheet.css';
</pre>
]]></description>
			<content:encoded><![CDATA[<p>After my <a href="http://edspencer.net/2009/07/printing-grids-with-ext-js.html">recent foray</a> into printing grids with ExtJS, I realised I needed to print some trees too. Seeing as some of the work was already done for the Grid example, it made sense to create a common API for printing any Ext.Component. And thus <a href="http://github.com/edspencer/Ext.ux.Printer">Ext.ux.Printer</a> was born:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({ // just a normal grid });
var tree = new Ext.tree.ColumnTree({ // just a normal column tree });

Ext.ux.Printer.print(grid);
Ext.ux.Printer.print(tree);
</pre>
<p>Each of the above opens a new window, renders some HTML (just a big table really), prints it and closes the window &#8211; all client side with no server side code required. Although trees and grids represent data quite differently internally, we can use the same API on Ext.ux.Printer to print them both.</p>
<p>Ext.ux.Printer uses Renderer classes to cope with a specific xtype, and adding Renderers for other components is easy. At the moment Ext.grid.GridPanel and Ext.tree.ColumnTree are supported out of the box, but let&#8217;s see how we&#8217;d add support for printing the contents of an Ext.Panel:</p>
<pre class="brush: jscript;">
/**
 * Prints the contents of an Ext.Panel
 */
Ext.ux.Printer.PanelRenderer = Ext.extend(Ext.ux.Printer.BaseRenderer, {

 /**
  * Generates the HTML fragment that will be rendered inside the &lt;html&gt; element of the printing window
  */
 generateBody: function(panel) {
   return String.format(&quot;&lt;div class='x-panel-print'&gt;{0}&lt;/div&gt;&quot;, panel.body.dom.innerHTML);
 }
});

Ext.ux.Printer.registerRenderer(&quot;panel&quot;, Ext.ux.Printer.PanelRenderer);
</pre>
<p>This is probably the simplest print renderer of all &#8211; we&#8217;re simply grabbing the HTML from inside a the panel&#8217;s body and returning it inside our own div.  We subclassed Ext.ux.Printer.BaseRenderer, and in this case all we needed to do was provide an implementation for generateBody. Whatever this function returns is rendered inside the &lt;body&gt; tag of the newly-opened printing window.</p>
<p>Notice that we registered this renderer for all components with the xtype of &#8216;panel&#8217;. Internally, Ext.ux.Printer examines the xtype chain of the component you pass it to print, and uses the first renderer that matches. As many Ext components inherit from Ext.Panel this can function as a catch-all renderer.</p>
<p>Here&#8217;s how we&#8217;d use our new renderer:</p>
<pre class="brush: jscript;">
var panel = new Ext.Panel({
  html: {
    tag: 'ul',
    chidren: [
      {tag: 'li', text: 'Item 1'},
      {tag: 'li', text: 'Item 2'},
      {tag: 'li', text: 'Item 3'}
    ]
  }
});

Ext.ux.Printer.print(panel);
</pre>
<p>Pretty straightforward. You can now print Ext.Panels the same way you&#8217;d print a Grid or a Tree. Take a look at the <a href="http://github.com/edspencer/Ext.ux.Printer/blob/master/renderers/GridPanel.js">Grid Renderer</a> and the <a href="http://github.com/edspencer/Ext.ux.Printer/blob/master/renderers/ColumnTree.js">ColumnTree Renderer</a> for examples of rendering more advanced components.</p>
<p>As usual, <a href="http://github.com/edspencer/Ext.ux.Printer">all of the Ext.ux.Printer source</a> is available on Github, and the README file there contains instructions for installation and usage.</p>
<p>Finally, when the printing window is opened it includes a stylesheet that it expects to find at &#8220;/stylesheets/print.css&#8221;. There is a default print.css stylesheet included with the extension to get you started, and you can specify where to find this stylesheet like this:</p>
<pre class="brush: jscript;">
Ext.ux.Printer.BaseRenderer.prototype.stylesheetPath = '/path/to/print/stylesheet.css';
</pre>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/07/extuxprinter-printing-for-any-ext.html/feed</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>ExtJS grid page size &#8211; letting the user decide</title>
		<link>http://edspencer.net/2009/07/extjs-grid-page-size-letting-user.html</link>
		<comments>http://edspencer.net/2009/07/extjs-grid-page-size-letting-user.html#comments</comments>
		<pubDate>Tue, 28 Jul 2009 07:28:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[extjs]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[paging]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=36</guid>
		<description><![CDATA[<p>Sometimes you&#8217;ll be using a Paging Toolbar on a grid and need to give the user the ability to change the number of records per page. One way of doing this is by adding a combobox to the toolbar:</p>
<pre class="brush: jscript;">
var combo = new Ext.form.ComboBox({
  name : 'perpage',
  width: 40,
  store: new Ext.data.ArrayStore({
    fields: ['id'],
    data  : [
      ['15'],
      ['25'],
      ['50']
    ]
  }),
  mode : 'local',
  value: '15',

  listWidth     : 40,
  triggerAction : 'all',
  displayField  : 'id',
  valueField    : 'id',
  editable      : false,
  forceSelection: true
});
</pre>
<p>We&#8217;ve set up a simple combo box which allows the user to choose between 15, 25 and 50 records per page. Now let&#8217;s set up a Paging Toolbar, and a listener to take action when the user changes the selection in the combo box:</p>
<pre class="brush: jscript;">
var bbar = new Ext.PagingToolbar({
  store:       store, //the store you use in your grid
  displayInfo: true,
  items   :    [
    '-',
    'Per Page: ',
    combo
  ]
});

combo.on('select', function(combo, record) {
  bbar.pageSize = parseInt(record.get('id'), 10);
  bbar.doLoad(bbar.cursor);
}, this);
</pre>
<p>Finally we&#8217;ll roll it all together into a Grid:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  //your grid setup here...

  bbar: bbar
});
</pre>
<p>If the user needs to be able to enter her own page size, replace the ComboBox with an Ext.form.NumberField, and attach the event listener to the field&#8217;s &#8216;keypress&#8217; event.</p>
]]></description>
			<content:encoded><![CDATA[<p>Sometimes you&#8217;ll be using a Paging Toolbar on a grid and need to give the user the ability to change the number of records per page. One way of doing this is by adding a combobox to the toolbar:</p>
<pre class="brush: jscript;">
var combo = new Ext.form.ComboBox({
  name : 'perpage',
  width: 40,
  store: new Ext.data.ArrayStore({
    fields: ['id'],
    data  : [
      ['15'],
      ['25'],
      ['50']
    ]
  }),
  mode : 'local',
  value: '15',

  listWidth     : 40,
  triggerAction : 'all',
  displayField  : 'id',
  valueField    : 'id',
  editable      : false,
  forceSelection: true
});
</pre>
<p>We&#8217;ve set up a simple combo box which allows the user to choose between 15, 25 and 50 records per page. Now let&#8217;s set up a Paging Toolbar, and a listener to take action when the user changes the selection in the combo box:</p>
<pre class="brush: jscript;">
var bbar = new Ext.PagingToolbar({
  store:       store, //the store you use in your grid
  displayInfo: true,
  items   :    [
    '-',
    'Per Page: ',
    combo
  ]
});

combo.on('select', function(combo, record) {
  bbar.pageSize = parseInt(record.get('id'), 10);
  bbar.doLoad(bbar.cursor);
}, this);
</pre>
<p>Finally we&#8217;ll roll it all together into a Grid:</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  //your grid setup here...

  bbar: bbar
});
</pre>
<p>If the user needs to be able to enter her own page size, replace the ComboBox with an Ext.form.NumberField, and attach the event listener to the field&#8217;s &#8216;keypress&#8217; event.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/07/extjs-grid-page-size-letting-user.html/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Printing grids with Ext JS</title>
		<link>http://edspencer.net/2009/07/printing-grids-with-ext-js.html</link>
		<comments>http://edspencer.net/2009/07/printing-grids-with-ext-js.html#comments</comments>
		<pubDate>Sun, 26 Jul 2009 14:43:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[extjs]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[print]]></category>
		<category><![CDATA[printing]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=35</guid>
		<description><![CDATA[<p>Grids are one of the most widely used components in Ext JS, and often represent data that the user would like to print. As the grid is usually part of a wider application, simply printing the page isn&#8217;t often a good solution.</p>
<p>You could attach a stylesheet with media=&#8221;print&#8221;, which hides all of the other items on the page, though this is rather application-specific, and a pain to update. It would be far better to have a reusable way of printing the data from any grid.</p>
<p>The way I went about this was to open up a new window, build a table containing the grid data into the new window, then print it and close. It&#8217;s actually pretty simple, and with a bit of CSS we can even get the printable view looking like it does in the grid.</p>
<p>Here&#8217;s how you use it (this is a slightly modified version of the <a href="http://extjs.com/deploy/dev/examples/grid/array-grid.html">Array Grid Example</a>):</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  store  : store,
  columns: [
      {header: &quot;Company&quot;,      width: 160, dataIndex: 'company'},
      {header: &quot;Price&quot;,        width: 75,  dataIndex: 'price', renderer: 'usMoney'},
      {header: &quot;Change&quot;,       width: 75,  dataIndex: 'change'},
      {header: &quot;% Change&quot;,     width: 75,  dataIndex: 'pctChange'}
      {header: &quot;Last Updated&quot;, width: 85,  dataIndex: 'lastChange', renderer: Ext.util.Format.dateRenderer('m/d/Y')}
  ],
  title:'Array Grid',
  tbar : [
    {
      text   : 'Print',
      iconCls: 'print',
      handler: function() {
        Ext.ux.GridPrinter.print(grid);
      }
    }
  ]
});
</pre>
<p>So we&#8217;ve just set up a simple grid with a print button in the top toolbar. The button just calls Ext.ux.GridPrinter.print, which does all the rest. The full source code that this example was based upon can be found at <a href="http://extjs.com/deploy/dev/examples/grid/array-grid.js">http://extjs.com/deploy/dev/examples/grid/array-grid.js</a>.</p>
<p>The source for the extension itself is pretty simple (<a href="http://gist.github.com/raw/155789/022585f76bf6b7f3523c41395ec158f19df69f8b/Ext.ux.GridPrinter.js">download it here</a>):</p>
<p><script src="http://gist.github.com/155789.js"></script></p>
<p>If you look at the source above you&#8217;ll see it includes a &#8216;print.css&#8217; stylesheet, which can be used to style the printable markup. The GridPrinter expects this stylesheet to be available at /stylesheets/print.css, but this is easy to change:</p>
<pre class="brush: jscript;">
  //add this before you call Ext.ux.GridPrinter.print
  Ext.ux.GridPrinter.stylesheetPath = '/some/other/path/gridPrint.css';
</pre>
<p>Finally, here is some CSS I&#8217;ve used to achieve a grid-like display on the printable page:</p>
<pre class="brush: css;">
html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}
img,body,html{border:0;}
address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}
ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}

table {
  width: 100%;
  text-align: left;
  font-size: 11px;
  font-family: arial;
  border-collapse: collapse;
}

table th {
  padding: 4px 3px 4px 5px;
  border: 1px solid #d0d0d0;
  border-left-color: #eee;
  background-color: #ededed;
}

table td {
  padding: 4px 3px 4px 5px;
  border-style: none solid solid;
  border-width: 1px;
  border-color: #ededed;
}
</pre>
<p>This technique could easily be adapted to print any component that uses a store &#8211; DataViews, ComboBoxes, Charts &#8211; whatever. It just requires changing the generated markup and stylesheet.</p>
]]></description>
			<content:encoded><![CDATA[<p>Grids are one of the most widely used components in Ext JS, and often represent data that the user would like to print. As the grid is usually part of a wider application, simply printing the page isn&#8217;t often a good solution.</p>
<p>You could attach a stylesheet with media=&#8221;print&#8221;, which hides all of the other items on the page, though this is rather application-specific, and a pain to update. It would be far better to have a reusable way of printing the data from any grid.</p>
<p>The way I went about this was to open up a new window, build a table containing the grid data into the new window, then print it and close. It&#8217;s actually pretty simple, and with a bit of CSS we can even get the printable view looking like it does in the grid.</p>
<p>Here&#8217;s how you use it (this is a slightly modified version of the <a href="http://extjs.com/deploy/dev/examples/grid/array-grid.html">Array Grid Example</a>):</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.GridPanel({
  store  : store,
  columns: [
      {header: &quot;Company&quot;,      width: 160, dataIndex: 'company'},
      {header: &quot;Price&quot;,        width: 75,  dataIndex: 'price', renderer: 'usMoney'},
      {header: &quot;Change&quot;,       width: 75,  dataIndex: 'change'},
      {header: &quot;% Change&quot;,     width: 75,  dataIndex: 'pctChange'}
      {header: &quot;Last Updated&quot;, width: 85,  dataIndex: 'lastChange', renderer: Ext.util.Format.dateRenderer('m/d/Y')}
  ],
  title:'Array Grid',
  tbar : [
    {
      text   : 'Print',
      iconCls: 'print',
      handler: function() {
        Ext.ux.GridPrinter.print(grid);
      }
    }
  ]
});
</pre>
<p>So we&#8217;ve just set up a simple grid with a print button in the top toolbar. The button just calls Ext.ux.GridPrinter.print, which does all the rest. The full source code that this example was based upon can be found at <a href="http://extjs.com/deploy/dev/examples/grid/array-grid.js">http://extjs.com/deploy/dev/examples/grid/array-grid.js</a>.</p>
<p>The source for the extension itself is pretty simple (<a href="http://gist.github.com/raw/155789/022585f76bf6b7f3523c41395ec158f19df69f8b/Ext.ux.GridPrinter.js">download it here</a>):</p>
<p><script src="http://gist.github.com/155789.js"></script></p>
<p>If you look at the source above you&#8217;ll see it includes a &#8216;print.css&#8217; stylesheet, which can be used to style the printable markup. The GridPrinter expects this stylesheet to be available at /stylesheets/print.css, but this is easy to change:</p>
<pre class="brush: jscript;">
  //add this before you call Ext.ux.GridPrinter.print
  Ext.ux.GridPrinter.stylesheetPath = '/some/other/path/gridPrint.css';
</pre>
<p>Finally, here is some CSS I&#8217;ve used to achieve a grid-like display on the printable page:</p>
<pre class="brush: css;">
html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}
img,body,html{border:0;}
address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}
ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}

table {
  width: 100%;
  text-align: left;
  font-size: 11px;
  font-family: arial;
  border-collapse: collapse;
}

table th {
  padding: 4px 3px 4px 5px;
  border: 1px solid #d0d0d0;
  border-left-color: #eee;
  background-color: #ededed;
}

table td {
  padding: 4px 3px 4px 5px;
  border-style: none solid solid;
  border-width: 1px;
  border-color: #ededed;
}
</pre>
<p>This technique could easily be adapted to print any component that uses a store &#8211; DataViews, ComboBoxes, Charts &#8211; whatever. It just requires changing the generated markup and stylesheet.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/07/printing-grids-with-ext-js.html/feed</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>Ext.override &#8211; Monkey Patching Ext JS</title>
		<link>http://edspencer.net/2009/07/extoverride-monkey-patching-ext-js.html</link>
		<comments>http://edspencer.net/2009/07/extoverride-monkey-patching-ext-js.html#comments</comments>
		<pubDate>Fri, 24 Jul 2009 07:00:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[danger]]></category>
		<category><![CDATA[extend]]></category>
		<category><![CDATA[override]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=34</guid>
		<description><![CDATA[<p>Ext JS contains a function called Ext.override.  Using this function allows you to add functionality to existing classes, as well as override properties of the class. For example, let&#8217;s say we want to override how Ext.Windows are hidden:</p>
<pre class="brush: jscript;">
Ext.override(Ext.Window, {
  hide: function() {
    //the contents of this function are now called instead of the default window hide function
  }
});
</pre>
<p>Using Ext.override changes the prototype of the class you are overriding &#8211; all instances of Ext.Window will now use the new hide function in the example above.</p>
<p>Overriding other classes can be dangerous, especially when they are classes from a library not under your control. For example, if the Ext.Window class was refactored in a later version, your overrides may no longer work. In some situations you might choose to go down the safer route of augmenting the existing functionality without overriding it. Here&#8217;s one way we can achieve this using a closure:</p>
<pre class="brush: jscript;">
(function() {
  var originalHide = Ext.Window.prototype.hide;

  Ext.override(Ext.Window, {
    hide: function() {
      //perform pre-processing
      alert(&quot;The window is about to close!&quot;);

      //call the original hide function
      originalHide.apply(this, arguments);

      //perform post-processing.
      alert(&quot;The window closed!!1&quot;);
    }
  });
})();
</pre>
<p>In the example above we set up a closure via an anonymous function which is executed immediately. This lets us keep a reference to the original hide function on Ext.Window. Underneath we perform the override itself, in which we provide our own logic.</p>
<p>The originalHide.apply(this, arguments) line is key to maintaining Ext.Window&#8217;s original functionality. By using the <a href="http://www.webreference.com/js/column26/apply.html">apply</a> keyword with the Window&#8217;s usual scope (&#8217;this&#8217;) and the function&#8217;s <a href="http://www.devguru.com/Technologies/Ecmascript/Quickref/arguments.html">arguments</a> &#8216;array&#8217;, we can wrap our functionality before or after the original method.</p>
<p>Augmenting in this way is safer than simply overwriting the function, or copy &#038; pasting Ext.Window&#8217;s original hide function into your own, as you don&#8217;t have to worry about breaking what Ext JS itself does (you&#8217;re still responsible for making sure your own additions work after upgrading Ext though).</p>
<p>Be aware that this will affect <b>all</b> instances of Ext.Window (or whatever class you are overriding). If that isn&#8217;t what you want, use <a href="http://edspencer.net/2008/08/cleaning-up-example-ext-js-form.html">Ext.extend to create your own subclasses</a> instead.</p>
<p>Finally, note that you can use Ext.override on any class, not just the built-in Ext ones &#8211; all it does internally is call Ext.apply on the constructor function&#8217;s prototype.</p>
]]></description>
			<content:encoded><![CDATA[<p>Ext JS contains a function called Ext.override.  Using this function allows you to add functionality to existing classes, as well as override properties of the class. For example, let&#8217;s say we want to override how Ext.Windows are hidden:</p>
<pre class="brush: jscript;">
Ext.override(Ext.Window, {
  hide: function() {
    //the contents of this function are now called instead of the default window hide function
  }
});
</pre>
<p>Using Ext.override changes the prototype of the class you are overriding &#8211; all instances of Ext.Window will now use the new hide function in the example above.</p>
<p>Overriding other classes can be dangerous, especially when they are classes from a library not under your control. For example, if the Ext.Window class was refactored in a later version, your overrides may no longer work. In some situations you might choose to go down the safer route of augmenting the existing functionality without overriding it. Here&#8217;s one way we can achieve this using a closure:</p>
<pre class="brush: jscript;">
(function() {
  var originalHide = Ext.Window.prototype.hide;

  Ext.override(Ext.Window, {
    hide: function() {
      //perform pre-processing
      alert(&quot;The window is about to close!&quot;);

      //call the original hide function
      originalHide.apply(this, arguments);

      //perform post-processing.
      alert(&quot;The window closed!!1&quot;);
    }
  });
})();
</pre>
<p>In the example above we set up a closure via an anonymous function which is executed immediately. This lets us keep a reference to the original hide function on Ext.Window. Underneath we perform the override itself, in which we provide our own logic.</p>
<p>The originalHide.apply(this, arguments) line is key to maintaining Ext.Window&#8217;s original functionality. By using the <a href="http://www.webreference.com/js/column26/apply.html">apply</a> keyword with the Window&#8217;s usual scope (&#8217;this&#8217;) and the function&#8217;s <a href="http://www.devguru.com/Technologies/Ecmascript/Quickref/arguments.html">arguments</a> &#8216;array&#8217;, we can wrap our functionality before or after the original method.</p>
<p>Augmenting in this way is safer than simply overwriting the function, or copy &#038; pasting Ext.Window&#8217;s original hide function into your own, as you don&#8217;t have to worry about breaking what Ext JS itself does (you&#8217;re still responsible for making sure your own additions work after upgrading Ext though).</p>
<p>Be aware that this will affect <b>all</b> instances of Ext.Window (or whatever class you are overriding). If that isn&#8217;t what you want, use <a href="http://edspencer.net/2008/08/cleaning-up-example-ext-js-form.html">Ext.extend to create your own subclasses</a> instead.</p>
<p>Finally, note that you can use Ext.override on any class, not just the built-in Ext ones &#8211; all it does internally is call Ext.apply on the constructor function&#8217;s prototype.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/07/extoverride-monkey-patching-ext-js.html/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

