<?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>Software Architect at Sencha, making Ext JS awesome</description>
	<lastBuildDate>Thu, 26 Aug 2010 02:30:08 +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>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>2</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>3</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>37</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>3</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>14</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>0</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>23</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>11</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>25</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>5</slash:comments>
		</item>
		<item>
		<title>Ext JS iterator functions</title>
		<link>http://edspencer.net/2009/07/ext-js-iterator-functions.html</link>
		<comments>http://edspencer.net/2009/07/ext-js-iterator-functions.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 11:46:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[arrays]]></category>
		<category><![CDATA[example]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=33</guid>
		<description><![CDATA[<p>Ext JS has a number of handy iterator functions. Some, like Ext.each, you probably already know about, but there are a few others lurking around which can be useful in saving yourself a few lines of code. First, let&#8217;s recap Ext.each:</p>
<h4>Ext.each</h4>
<p>Ext.each applies a function to each member of an array. It&#8217;s basically a more convenient form of a for loop:</p>
<pre class="brush: jscript;">
var people = ['Bill', 'Saul', 'Gaius'];

//using each to detect Cylons:
Ext.each(people, function(person, index) {
  var cylon = (index + 1) % 2 == 0; //every second man is a toaster
  alert(person + (cylon ? ' is ' : ' is not ') + 'a fraking cylon');
});

//is the same as
for (var i=0; i &lt; people.length; i++) {
  var person = people[i];
  var cylon = (index + 1) % 2 == 0; //every second man is a toaster

  alert(person + (cylon ? ' is ' : ' is not ') + 'a frakin cylon');
};
</pre>
<h4>Ext.iterate</h4>
<p>Ext.iterate is like Ext.each for non-array objects. Use it wherever you would normally use a for .. in loop:</p>
<pre class="brush: jscript;">
var ships  = {'Bill': 'Galactica', 'Laura': 'Colonial One'};

Ext.iterate(ships, function(key, value) {
  alert(key + &quot;'s ship is the &quot; + value);
});

//is the same as
for (key in ships) {
  var value = ships[key];
  alert(key + &quot;'s ship is the &quot; + value);
}
</pre>
<p>Using Ext.iterate with an array is the same as calling Ext.each. Each and Iterate both take an optional third parameter, which is the scope to run the function in. Another advantage over using the for construct is that you can easily reuse the same function:</p>
<pre class="brush: jscript;">
var myFunction = function(item, index) {
  //does some clever thing
}

Ext.each(people, myFunction);
Ext.each(['another', 'array'], myFunction);
</pre>
<h4>Ext.pluck</h4>
<p>Ext.pluck grabs the specified property from an array of objects:</p>
<pre class="brush: jscript;">
var animals = [
  {name: 'Ed', species: 'Unknown'},
  {name: 'Bumble', species: 'Cat'},
  {name: 'Triumph', species: 'Insult Dog'}
];

Ext.pluck(animals, 'species'); //returns ['Unknown', 'Cat', 'Insult Dog']
Ext.pluck(animals, 'name'); //returns ['Ed', 'Bumble', 'Triumph']
</pre>
<h4>Ext.invoke</h4>
<p>Invoke allows a function to be applied to all members of an array, and returns the results. Using our animals object from above:</p>
<pre class="brush: jscript;">
var describeAnimal = function(animal) {
  return String.format(&quot;{0} is a {1}&quot;, animal.name, animal.species);
}

var describedAnimals = Ext.invoke(animals, describeAnimal);
console.log(describedAnimals); // ['Ed is a Unknown', 'Bumble is a Cat', 'Triumph is a Insult Dog'];
</pre>
<p>Ext.invoke performs a similar job to Ruby&#8217;s collect method in making it easy to transform arrays. Any additional arguments passed to the Ext.invoke call will be passed as arguments to your function, in this case the describeAnimal function. Obviously your functions will be much more grammatically accurate than mine.</p>
<h4>Ext.partition</h4>
<p>Ext.Partition splits an array into two sets based on a function you provide:</p>
<pre class="brush: jscript;">
var trees = [
  {name: 'Oak',    height: 20},
  {name: 'Willow', height: 10},
  {name: 'Cactus', height: 5}
];

var isTall = function(tree) {return tree.height &gt; 15};

Ext.partition(trees, isTall);

//returns:
[
  [{name: 'Oak', height: 20}],
  [{name: 'Willow', height: 10}, {name: 'Cactus', height: 5}]
]
</pre>
<p>The partition call above returns a 2-dimensional array with the first element containing all of the items for which the function returned true (tall trees in this case), and the second containing items for which the function return false.</p>
<h4>Math functions</h4>
<p>Finally, we have some simple math-related functions:</p>
<pre class="brush: jscript;">
var numbers = [1, 2, 3, 4, 5];
Ext.min(numbers); //1
Ext.max(numbers); //5
Ext.sum(numbers); //15
Ext.mean(numbers); //3
</pre>
<p>While the built in functions don&#8217;t cater for all situations, they&#8217;re useful to have and to know about, and usually offer a more elegant approach than using the &#8216;for&#8217; keyword.</p>
]]></description>
			<content:encoded><![CDATA[<p>Ext JS has a number of handy iterator functions. Some, like Ext.each, you probably already know about, but there are a few others lurking around which can be useful in saving yourself a few lines of code. First, let&#8217;s recap Ext.each:</p>
<h4>Ext.each</h4>
<p>Ext.each applies a function to each member of an array. It&#8217;s basically a more convenient form of a for loop:</p>
<pre class="brush: jscript;">
var people = ['Bill', 'Saul', 'Gaius'];

//using each to detect Cylons:
Ext.each(people, function(person, index) {
  var cylon = (index + 1) % 2 == 0; //every second man is a toaster
  alert(person + (cylon ? ' is ' : ' is not ') + 'a fraking cylon');
});

//is the same as
for (var i=0; i &lt; people.length; i++) {
  var person = people[i];
  var cylon = (index + 1) % 2 == 0; //every second man is a toaster

  alert(person + (cylon ? ' is ' : ' is not ') + 'a frakin cylon');
};
</pre>
<h4>Ext.iterate</h4>
<p>Ext.iterate is like Ext.each for non-array objects. Use it wherever you would normally use a for .. in loop:</p>
<pre class="brush: jscript;">
var ships  = {'Bill': 'Galactica', 'Laura': 'Colonial One'};

Ext.iterate(ships, function(key, value) {
  alert(key + &quot;'s ship is the &quot; + value);
});

//is the same as
for (key in ships) {
  var value = ships[key];
  alert(key + &quot;'s ship is the &quot; + value);
}
</pre>
<p>Using Ext.iterate with an array is the same as calling Ext.each. Each and Iterate both take an optional third parameter, which is the scope to run the function in. Another advantage over using the for construct is that you can easily reuse the same function:</p>
<pre class="brush: jscript;">
var myFunction = function(item, index) {
  //does some clever thing
}

Ext.each(people, myFunction);
Ext.each(['another', 'array'], myFunction);
</pre>
<h4>Ext.pluck</h4>
<p>Ext.pluck grabs the specified property from an array of objects:</p>
<pre class="brush: jscript;">
var animals = [
  {name: 'Ed', species: 'Unknown'},
  {name: 'Bumble', species: 'Cat'},
  {name: 'Triumph', species: 'Insult Dog'}
];

Ext.pluck(animals, 'species'); //returns ['Unknown', 'Cat', 'Insult Dog']
Ext.pluck(animals, 'name'); //returns ['Ed', 'Bumble', 'Triumph']
</pre>
<h4>Ext.invoke</h4>
<p>Invoke allows a function to be applied to all members of an array, and returns the results. Using our animals object from above:</p>
<pre class="brush: jscript;">
var describeAnimal = function(animal) {
  return String.format(&quot;{0} is a {1}&quot;, animal.name, animal.species);
}

var describedAnimals = Ext.invoke(animals, describeAnimal);
console.log(describedAnimals); // ['Ed is a Unknown', 'Bumble is a Cat', 'Triumph is a Insult Dog'];
</pre>
<p>Ext.invoke performs a similar job to Ruby&#8217;s collect method in making it easy to transform arrays. Any additional arguments passed to the Ext.invoke call will be passed as arguments to your function, in this case the describeAnimal function. Obviously your functions will be much more grammatically accurate than mine.</p>
<h4>Ext.partition</h4>
<p>Ext.Partition splits an array into two sets based on a function you provide:</p>
<pre class="brush: jscript;">
var trees = [
  {name: 'Oak',    height: 20},
  {name: 'Willow', height: 10},
  {name: 'Cactus', height: 5}
];

var isTall = function(tree) {return tree.height &gt; 15};

Ext.partition(trees, isTall);

//returns:
[
  [{name: 'Oak', height: 20}],
  [{name: 'Willow', height: 10}, {name: 'Cactus', height: 5}]
]
</pre>
<p>The partition call above returns a 2-dimensional array with the first element containing all of the items for which the function returned true (tall trees in this case), and the second containing items for which the function return false.</p>
<h4>Math functions</h4>
<p>Finally, we have some simple math-related functions:</p>
<pre class="brush: jscript;">
var numbers = [1, 2, 3, 4, 5];
Ext.min(numbers); //1
Ext.max(numbers); //5
Ext.sum(numbers); //15
Ext.mean(numbers); //3
</pre>
<p>While the built in functions don&#8217;t cater for all situations, they&#8217;re useful to have and to know about, and usually offer a more elegant approach than using the &#8216;for&#8217; keyword.</p>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/07/ext-js-iterator-functions.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>The case for Ext.applyOnly</title>
		<link>http://edspencer.net/2009/04/case-for-extapplyonly.html</link>
		<comments>http://edspencer.net/2009/04/case-for-extapplyonly.html#comments</comments>
		<pubDate>Thu, 23 Apr 2009 08:49:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[extjs]]></category>
		<category><![CDATA[apply]]></category>
		<category><![CDATA[methods]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=28</guid>
		<description><![CDATA[<p>** Update: Ext 3.0RC1 has included something like this, but called Ext.copyTo.  Obviously my name is better though **</p>
<p>We should have something like this:</p>
<pre class="brush: jscript;">
Ext.applyOnly(this, config, ['width', 'height']);
</pre>
<p>You could use this every time you write a method or class that requires a config Object as one of it&#8217;s parameters.  These methods ought to only apply those properties of the config object they actually need, but usually this will just be done with an Ext.apply(this, config).  This means anything in your object could be overwritten by this config object. Sometimes that&#8217;s a good thing, but sometimes it&#8217;s definitely not.</p>
<p>Ext.applyOnly() applies only a whitelist of the properties in the config object.  These are specified by an optional third argument, which is an array of property names. Here&#8217;s how you might write applyOnly:</p>
<pre class="brush: jscript;">
/**
 * Applies only a pre-specified set of properties from one object to another
 * @param {Object} receiver The object to copy the properties to
 * @param {Object} sender The object to copy the properties from
 * @param {Array} whitelist The whitelist of properties to copy (e.g. ['width', 'height'])
 * @return {Object} The receiver object, with any of the whitelisted properties overwritten if they exist in sender
 */
Ext.applyOnly = function(receiver, sender, whitelist) {
  if (receiver &amp;&amp; sender) {
    Ext.each(whitelist || [], function(item) {
      if (typeof sender[item] != 'undefined') receiver[item] = sender[item];
    }, this);
  };

  return receiver;
};
</pre>
<p>While you can&#8217;t stop code maliciously overwriting properties this way, it would stop people from unknowingly overwriting your object&#8217;s properties.  They could overwrite them manually, but they&#8217;ll do this knowing that this wasn&#8217;t an intended use for the class. Let&#8217;s have a look at an extension that would do a great job opening popups telling people they&#8217;ve won lots of money:</p>
<pre class="brush: jscript;">
/**
 * Pops up windows telling lucky visitor she's won big money!!!!
 */
Ext.ux.WinnerEarnings = Ext.extend(Ext.util.Observable, {
  /**
   * @property accessibleProperties
   * @type Array
   * All properties intended to be mass-updatable
   */
  accessibleProperties: ['height', 'width'],

  /**
   * Message to show lucky winners!! You can't change this!!!!!
   */
  message: &quot;You're the 1000000000000th visitor!!!!!!!1 Click here to claim money. Now!!!&quot;,

  constructor: function(config) {
    //apply only the fields that are deemed writable
    Ext.applyOnly(this, config, this.accessibleProperties);

    Ext.ux.WinnerEarnings.superclass.constructor.apply(this, arguments);

    Ext.applyIf(this, {
      version: 2.9,
      coolFeature: Ext.util.TaskRunner({
        interval: 1000,
        scope:    this,
        run: function() {
          //version, coolFeature, updateDetails, closable and close won't be sent to Ext.Window
          new Ext.Window(Ext.applyOnly({}, this, ['height', 'weight', 'message'])).show();
        }
      }).start()
    }
  },

  /**
   * Updates this WinnerEarnings opportunity with options from the supplied object
   * @param {Object} updates An object containing updates to make to this precious opportunity
   * @return {Ext.ux.WinnerEarnings} The WinnerEarnings object
   */
  updateDetails: function(updates) {
    return Ext.applyOnly(this, updates, this.accessibleProperties)
  },

  //secret tricks to let the user stop the popups
  closable: false,
  close: function() {
    this.coolFeature.stop();
  }
})
</pre>
<p>How it works:</p>
<pre class="brush: jscript;">
var myObj = new Ext.ux.WinnerEarnings({height: 200, width: 150});

myObj.updateDetails({width: 300, message: &quot;My Message&quot;})
myObj.width:   // =&gt; 300
myObj.message; // =&gt; &quot;You're the 1000000000000th visitor!!!!!!!1 Click here to claim money. Now!!!&quot;

//updating message didn't work, but we can still do it manually
myObj.message = &quot;My message&quot;;
myObj.message; // =&gt; &quot;My message&quot;
</pre>
<p>In my example class I&#8217;ve added the whitelist as an accessibleProperties property on the class, which makes it easy for others to see what they should and should not be updating.</p>
<p>In this example we&#8217;re also sanitizing output with applyOnly.  WinnerEarnings lightly wraps around a series of Ext.Windows and we&#8217;d like to be able to pass our WinnerEarnings object as config. We want to make sure we&#8217;re not passing our &#8216;closable&#8217; property, &#8216;close()&#8217; function and others to the Ext.Window constructor, so we pass that in via a whitelist too, inside the run() function in our constructor.<br />
<a href="http://github.com/edspencer/ext.applyonly/blob/98bf85dc08b71d774a4b0d5d14b5153ad5250970/applyOnly.spec.js"><br />
Check out the unit tests</a> for the function to see a couple more use cases. Here&#8217;s one final example &#8211; sanitizing output from a function:</p>
<pre class="brush: jscript;">
myFunction = function(input) {
  //do some stuff to make input useful

  //guarantee our returned object only has relevant properties
  return Ext.applyOnly({}, input, ['important-thing-1', 'important-thing-2']);
}
</pre>
]]></description>
			<content:encoded><![CDATA[<p>** Update: Ext 3.0RC1 has included something like this, but called Ext.copyTo.  Obviously my name is better though **</p>
<p>We should have something like this:</p>
<pre class="brush: jscript;">
Ext.applyOnly(this, config, ['width', 'height']);
</pre>
<p>You could use this every time you write a method or class that requires a config Object as one of it&#8217;s parameters.  These methods ought to only apply those properties of the config object they actually need, but usually this will just be done with an Ext.apply(this, config).  This means anything in your object could be overwritten by this config object. Sometimes that&#8217;s a good thing, but sometimes it&#8217;s definitely not.</p>
<p>Ext.applyOnly() applies only a whitelist of the properties in the config object.  These are specified by an optional third argument, which is an array of property names. Here&#8217;s how you might write applyOnly:</p>
<pre class="brush: jscript;">
/**
 * Applies only a pre-specified set of properties from one object to another
 * @param {Object} receiver The object to copy the properties to
 * @param {Object} sender The object to copy the properties from
 * @param {Array} whitelist The whitelist of properties to copy (e.g. ['width', 'height'])
 * @return {Object} The receiver object, with any of the whitelisted properties overwritten if they exist in sender
 */
Ext.applyOnly = function(receiver, sender, whitelist) {
  if (receiver &amp;&amp; sender) {
    Ext.each(whitelist || [], function(item) {
      if (typeof sender[item] != 'undefined') receiver[item] = sender[item];
    }, this);
  };

  return receiver;
};
</pre>
<p>While you can&#8217;t stop code maliciously overwriting properties this way, it would stop people from unknowingly overwriting your object&#8217;s properties.  They could overwrite them manually, but they&#8217;ll do this knowing that this wasn&#8217;t an intended use for the class. Let&#8217;s have a look at an extension that would do a great job opening popups telling people they&#8217;ve won lots of money:</p>
<pre class="brush: jscript;">
/**
 * Pops up windows telling lucky visitor she's won big money!!!!
 */
Ext.ux.WinnerEarnings = Ext.extend(Ext.util.Observable, {
  /**
   * @property accessibleProperties
   * @type Array
   * All properties intended to be mass-updatable
   */
  accessibleProperties: ['height', 'width'],

  /**
   * Message to show lucky winners!! You can't change this!!!!!
   */
  message: &quot;You're the 1000000000000th visitor!!!!!!!1 Click here to claim money. Now!!!&quot;,

  constructor: function(config) {
    //apply only the fields that are deemed writable
    Ext.applyOnly(this, config, this.accessibleProperties);

    Ext.ux.WinnerEarnings.superclass.constructor.apply(this, arguments);

    Ext.applyIf(this, {
      version: 2.9,
      coolFeature: Ext.util.TaskRunner({
        interval: 1000,
        scope:    this,
        run: function() {
          //version, coolFeature, updateDetails, closable and close won't be sent to Ext.Window
          new Ext.Window(Ext.applyOnly({}, this, ['height', 'weight', 'message'])).show();
        }
      }).start()
    }
  },

  /**
   * Updates this WinnerEarnings opportunity with options from the supplied object
   * @param {Object} updates An object containing updates to make to this precious opportunity
   * @return {Ext.ux.WinnerEarnings} The WinnerEarnings object
   */
  updateDetails: function(updates) {
    return Ext.applyOnly(this, updates, this.accessibleProperties)
  },

  //secret tricks to let the user stop the popups
  closable: false,
  close: function() {
    this.coolFeature.stop();
  }
})
</pre>
<p>How it works:</p>
<pre class="brush: jscript;">
var myObj = new Ext.ux.WinnerEarnings({height: 200, width: 150});

myObj.updateDetails({width: 300, message: &quot;My Message&quot;})
myObj.width:   // =&gt; 300
myObj.message; // =&gt; &quot;You're the 1000000000000th visitor!!!!!!!1 Click here to claim money. Now!!!&quot;

//updating message didn't work, but we can still do it manually
myObj.message = &quot;My message&quot;;
myObj.message; // =&gt; &quot;My message&quot;
</pre>
<p>In my example class I&#8217;ve added the whitelist as an accessibleProperties property on the class, which makes it easy for others to see what they should and should not be updating.</p>
<p>In this example we&#8217;re also sanitizing output with applyOnly.  WinnerEarnings lightly wraps around a series of Ext.Windows and we&#8217;d like to be able to pass our WinnerEarnings object as config. We want to make sure we&#8217;re not passing our &#8216;closable&#8217; property, &#8216;close()&#8217; function and others to the Ext.Window constructor, so we pass that in via a whitelist too, inside the run() function in our constructor.<br />
<a href="http://github.com/edspencer/ext.applyonly/blob/98bf85dc08b71d774a4b0d5d14b5153ad5250970/applyOnly.spec.js"><br />
Check out the unit tests</a> for the function to see a couple more use cases. Here&#8217;s one final example &#8211; sanitizing output from a function:</p>
<pre class="brush: jscript;">
myFunction = function(input) {
  //do some stuff to make input useful

  //guarantee our returned object only has relevant properties
  return Ext.applyOnly({}, input, ['important-thing-1', 'important-thing-2']);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/04/case-for-extapplyonly.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Force Ext.data.Store to use GET</title>
		<link>http://edspencer.net/2009/02/force-extdatastore-to-use-get.html</link>
		<comments>http://edspencer.net/2009/02/force-extdatastore-to-use-get.html#comments</comments>
		<pubDate>Wed, 11 Feb 2009 15:23:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[post]]></category>
		<category><![CDATA[store]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=25</guid>
		<description><![CDATA[<p>Say you have a simple Ext store:</p>
<pre class="brush: jscript;">
var myStore = new Ext.data.Store({
  url:    '/widgets.json',
  reader: someReader
});
</pre>
<p>Which you put in a grid, along with a paging toolbar:</p>
<pre class="brush: jscript;">
var myGrid = new Ext.grid.GridPanel({
  store:   myStore,
  columns: [.....],
  bbar:    new Ext.PagingToolbar({
    store: myStore
  })
  ... etc ...
});
</pre>
<p>Your grid loads up and the store performs a GET request to /widgets.json, which returns your widgets along with a total (<a href="http://extjs.com/deploy/dev/examples/grid/paging.html">see an example</a>).</p>
<p>Awesome, but now we click one of the paging buttons on the PagingToolbar and we have a problem &#8211; our request has turned into POST /widgets.json, with &#8220;start=20&#8243; and &#8220;limit=20&#8243; as POST params.</p>
<p>Now we don&#8217;t really want that &#8211; we&#8217;re not POSTing any data to the server after all, we&#8217;re just trying to GET some.  If you&#8217;re using a nice RESTful API on your server side this may cause you a real problem, as POST /widgets will likely be taken as an attempt to create a new Widget.</p>
<p>Luckily, as with most things the solution is simple if you know how.  An <a href="http://extjs.com/deploy/dev/docs/?class=Ext.data.Store">Ext.data.Store</a> delegates loading its data off to an <a href="http://extjs.com/deploy/dev/docs/?class=Ext.data.DataProxy">Ext.data.DataProxy</a> subclass.  By default your store will create an <a href="http://extjs.com/deploy/dev/docs/?class=Ext.data.HttpProxy">Ext.data.HttpProxy</a> using the url: &#8216;/widgets.json&#8217; you passed in your store config.  To make sure your stores are always requesting data using GET, just provide a proxy like this:</p>
<pre class="brush: jscript;">
var myStore = new Ext.data.Store({
  proxy: new Ext.data.HttpProxy({
    url:    '/widgets.json',
    method: 'GET'
  }),
  reader: someReader
});
</pre>
]]></description>
			<content:encoded><![CDATA[<p>Say you have a simple Ext store:</p>
<pre class="brush: jscript;">
var myStore = new Ext.data.Store({
  url:    '/widgets.json',
  reader: someReader
});
</pre>
<p>Which you put in a grid, along with a paging toolbar:</p>
<pre class="brush: jscript;">
var myGrid = new Ext.grid.GridPanel({
  store:   myStore,
  columns: [.....],
  bbar:    new Ext.PagingToolbar({
    store: myStore
  })
  ... etc ...
});
</pre>
<p>Your grid loads up and the store performs a GET request to /widgets.json, which returns your widgets along with a total (<a href="http://extjs.com/deploy/dev/examples/grid/paging.html">see an example</a>).</p>
<p>Awesome, but now we click one of the paging buttons on the PagingToolbar and we have a problem &#8211; our request has turned into POST /widgets.json, with &#8220;start=20&#8243; and &#8220;limit=20&#8243; as POST params.</p>
<p>Now we don&#8217;t really want that &#8211; we&#8217;re not POSTing any data to the server after all, we&#8217;re just trying to GET some.  If you&#8217;re using a nice RESTful API on your server side this may cause you a real problem, as POST /widgets will likely be taken as an attempt to create a new Widget.</p>
<p>Luckily, as with most things the solution is simple if you know how.  An <a href="http://extjs.com/deploy/dev/docs/?class=Ext.data.Store">Ext.data.Store</a> delegates loading its data off to an <a href="http://extjs.com/deploy/dev/docs/?class=Ext.data.DataProxy">Ext.data.DataProxy</a> subclass.  By default your store will create an <a href="http://extjs.com/deploy/dev/docs/?class=Ext.data.HttpProxy">Ext.data.HttpProxy</a> using the url: &#8216;/widgets.json&#8217; you passed in your store config.  To make sure your stores are always requesting data using GET, just provide a proxy like this:</p>
<pre class="brush: jscript;">
var myStore = new Ext.data.Store({
  proxy: new Ext.data.HttpProxy({
    url:    '/widgets.json',
    method: 'GET'
  }),
  reader: someReader
});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/02/force-extdatastore-to-use-get.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding a loading mask to your ExtJS application</title>
		<link>http://edspencer.net/2009/02/adding-loading-mask-to-your-extjs.html</link>
		<comments>http://edspencer.net/2009/02/adding-loading-mask-to-your-extjs.html#comments</comments>
		<pubDate>Sun, 01 Feb 2009 15:55:00 +0000</pubDate>
		<dc:creator>Ed Spencer</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[loading]]></category>
		<category><![CDATA[mask]]></category>

		<guid isPermaLink="false">http://192.168.2.15/Projects/wordpress/?p=24</guid>
		<description><![CDATA[<p>Adding a loading mask like the one on the <a href="http://extjs.com/deploy/dev/docs/">ExtJS API application</a> is a nice way of showing the user that something is happening while their browser downloads the source code.  It&#8217;s also extremely easy to do.</p>
<p>First, place the following HTML above all of your javascript include tags, ideally just after the &lt;body&gt; tag:</p>
<pre class="brush: xml;">
&lt;div id=&quot;loading-mask&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;loading&quot;&gt;
  &lt;div class=&quot;loading-indicator&quot;&gt;
    Loading...
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>If you are currently including javascript files inside the &lt;head&gt;, don&#8217;t &#8211; <a href="http://developer.yahoo.com/performance/rules.html#js_bottom">put them at the bottom</a>.</p>
<p>With a bit of CSS (see below), this provides a white mask over all underlying content, and a loading message.  When everything has loaded, remove the mask like this:</p>
<pre class="brush: jscript;">
Ext.onReady(function() {
  setTimeout(function(){
    Ext.get('loading').remove();
    Ext.get('loading-mask').fadeOut({remove:true});
  }, 250);
});
</pre>
<p>The above simply fades out the HTML elements to reveal the now ready page.  The setTimeout call gives your app a little time to render, which is useful if you&#8217;re doing something like pulling external content down from the server.</p>
<p>Finally, here&#8217;s the CSS I use to style up the loading mask.  You&#8217;ll need to <a href="http://extjs.com/deploy/dev/docs/resources/extanim32.gif">download a loading image</a> and stick it in the appropriate directory.</p>
<pre class="brush: css;">
#loading-mask {
  position: absolute;
  left:     0;
  top:      0;
  width:    100%;
  height:   100%;
  z-index:  20000;
  background-color: white;
}

#loading {
  position: absolute;
  left:     50%;
  top:      50%;
  padding:  2px;
  z-index:  20001;
  height:   auto;
  margin:   -35px 0 0 -30px;
}

#loading .loading-indicator {
  background: url(../images/loading.gif) no-repeat;
  color:      #555;
  font:       bold 13px tahoma,arial,helvetica;
  padding:    8px 42px;
  margin:     0;
  text-align: center;
  height:     auto;
}
</pre>
]]></description>
			<content:encoded><![CDATA[<p>Adding a loading mask like the one on the <a href="http://extjs.com/deploy/dev/docs/">ExtJS API application</a> is a nice way of showing the user that something is happening while their browser downloads the source code.  It&#8217;s also extremely easy to do.</p>
<p>First, place the following HTML above all of your javascript include tags, ideally just after the &lt;body&gt; tag:</p>
<pre class="brush: xml;">
&lt;div id=&quot;loading-mask&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;loading&quot;&gt;
  &lt;div class=&quot;loading-indicator&quot;&gt;
    Loading...
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>If you are currently including javascript files inside the &lt;head&gt;, don&#8217;t &#8211; <a href="http://developer.yahoo.com/performance/rules.html#js_bottom">put them at the bottom</a>.</p>
<p>With a bit of CSS (see below), this provides a white mask over all underlying content, and a loading message.  When everything has loaded, remove the mask like this:</p>
<pre class="brush: jscript;">
Ext.onReady(function() {
  setTimeout(function(){
    Ext.get('loading').remove();
    Ext.get('loading-mask').fadeOut({remove:true});
  }, 250);
});
</pre>
<p>The above simply fades out the HTML elements to reveal the now ready page.  The setTimeout call gives your app a little time to render, which is useful if you&#8217;re doing something like pulling external content down from the server.</p>
<p>Finally, here&#8217;s the CSS I use to style up the loading mask.  You&#8217;ll need to <a href="http://extjs.com/deploy/dev/docs/resources/extanim32.gif">download a loading image</a> and stick it in the appropriate directory.</p>
<pre class="brush: css;">
#loading-mask {
  position: absolute;
  left:     0;
  top:      0;
  width:    100%;
  height:   100%;
  z-index:  20000;
  background-color: white;
}

#loading {
  position: absolute;
  left:     50%;
  top:      50%;
  padding:  2px;
  z-index:  20001;
  height:   auto;
  margin:   -35px 0 0 -30px;
}

#loading .loading-indicator {
  background: url(../images/loading.gif) no-repeat;
  color:      #555;
  font:       bold 13px tahoma,arial,helvetica;
  padding:    8px 42px;
  margin:     0;
  text-align: center;
  height:     auto;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://edspencer.net/2009/02/adding-loading-mask-to-your-extjs.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
