<?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>existdissolve.com &#187; ExtJS</title>
	<atom:link href="http://existdissolve.com/category/javascript/ext/feed/" rel="self" type="application/rss+xml" />
	<link>http://existdissolve.com</link>
	<description>the singularity of being and nothingness</description>
	<lastBuildDate>Wed, 16 May 2012 12:54:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>ExtJS 4: Applying Model Validations to Forms</title>
		<link>http://existdissolve.com/2012/04/extjs-4-applying-model-validations-to-forms/</link>
		<comments>http://existdissolve.com/2012/04/extjs-4-applying-model-validations-to-forms/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 12:28:49 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Model Validations]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2398</guid>
		<description><![CDATA[One of my absolute favorite things about ExtJS&#8217; data model is how simple it is to apply a Model instance to a form. If you&#8217;ve never done this before, consider the following data model: Ext.define('Validations.model.Person', {     extend: 'Ext.data.Model',     fields: [         {name:"name", type:'string'},         {name:"age",&#8230;]]></description>
			<content:encoded><![CDATA[<p>One of my absolute favorite things about <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model">ExtJS&#8217; data model</a> is how simple it is to apply a Model instance to a form. If you&#8217;ve never done this before, consider the following data model:</p>
<pre>Ext.define('Validations.model.Person', {
    extend: 'Ext.data.Model',
    fields: [
        {name:"name", type:'string'},
        {name:"age", type:"int"},
        {name:"hobby", type:"string"}
    ]
})</pre>
<p>Also, assume we have a form defined like so:</p>
<pre>Ext.define('Validations.view.people.Form', {
    extend: 'Ext.form.Panel',
    alias: 'widget.peopleform',
    bodyPadding: 10,
    border: false,
    initComponent: function() {
        var me = this;
        Ext.applyIf(me, {
            defaults: {
                width: 250,
                labelWidth: 70
            },
            items: [
                {
                    xtype: 'textfield',
                    name: 'name',
                    id: 'name',
                    fieldLabel: 'Name'
                },
                {
                    xtype: 'numberfield',
                    name: 'age',
                    id: 'age',
                    fieldLabel: 'Age',
                    value: 20
                },
                {
                    xtype: 'textfield',
                    name: 'hobby',
                    id: 'hobby',
                    fieldLabel: 'Hobby'
                }
            ]
        });
        me.callParent(arguments);
    }
})</pre>
<p><strong>NOTE:</strong> Notice that the &#8220;name&#8221; properties of each form field maps 1:1 with the &#8220;name&#8221; properties in my Model.</p>
<p>Now, let&#8217;s say that we want to edit a Model instance. We could, of course, manually set the value of each form field to that of the corresponding field in the Model. However, this is clunky and unnecessary, given that the form itself has a method for doing this automatically. Consider the following:</p>
<pre>// get first model instance in store
 myrecord = somestore.getAt(0)
 // load form with data from selected model instance
 myform.loadRecord(myrecord)</pre>
<p>Pretty simple, right? When calling the <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.Basic-method-loadRecord">loadRecord()</a> method on the form, any field in the form whose name value matches the name definition in the specified Model will be loaded with the data of that particular field.</p>
<blockquote><p>Try it out. Open the demo, and double-click on any record in the grid. On the itemdblclick event of the grid, the form&#8217;s loadRecord() method is invoked, and the Model data corresponding to the clicked row in the grid is applied to the form&#8217;s fields</p></blockquote>
<h2>Validation, Validation, Validation</h2>
<p>So that&#8217;s pretty easy. But of course, when dealing with data&#8211;whether on the Model or in a form&#8211;you&#8217;re going to want to validate it to make sure that you have the data you&#8217;re expecting, and that the data is in the right format.</p>
<p>In ExtJS, there are a few different ways you can validate Model data.</p>
<p><strong>First</strong>, you can apply validations directly to the model itself. For example, let&#8217;s add in a few to the Model already setup:</p>
<pre>Ext.define('Validations.model.Person', {
    extend: 'Ext.data.Model',
    fields: [
        {name:"name", type:'string'},
        {name:"age", type:"int"},
        {name:"hobby", type:"string"}
    ],
    ,
    validations: [
        {type: 'presence', field: 'name', message: 'You have to enter a name, silly'},
        {type: 'presence', field: 'age', message: 'You must specify an age'},
        {type: 'presence', field: 'hobby', message: 'You must enter a hobby'},
        {type: 'length', field: 'hobby', min:5, message: 'You must specify a hobby with more than 4 characters'}
    ]
})</pre>
<p>In this example, I&#8217;ve applied a &#8220;presence&#8221; validation to each field, which requires that each field has a value, as well as a &#8220;length&#8221; validation to the &#8220;hobby&#8221; field. When calling the Model&#8217;s validate() method, the instance&#8217;s current data will be run through the validations.</p>
<p>The second, albeit indirect, way to validate the Model is to apply validations to the form fields themselves, such as defining properties like <strong>allowBlank</strong> (e.g., &#8220;presence&#8221;), specifying a custom <strong>vType</strong> for the field, using a regex, etc.</p>
<p>While both of these approaches are great, they are not particularly related. For example, if we have NO validations whatsoever on the form, we could submit perfectly valid Form data, but this data may yet trigger validations when the Model is validated. By default, the form doesn&#8217;t care about the Model-level validations, and will only trigger Form-level validations that have been defined.</p>
<h2>Applying Model Validation to Form Fields</h2>
<p>While this disconnect is certainly understandable, I thought it would be cool if both validations could be supported when the form is being validated. Here&#8217;s a short list of my requirements:</p>
<ul>
<li>Model validations should be enforced at a field by field level (e.g., if there are two validations for &#8220;name&#8221;, these should both be enforced on the &#8220;name&#8221; field in the form)</li>
<li>Both Model and Form field validations should be respected</li>
<li>Both Model and Form field validations should be communicated to the user</li>
</ul>
<p>So how to do this? While there are probably a dozen ways to accomplish this goal, the approach I took was to simply override <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.Basic">Ext.form.Basic</a> and <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.field.Base">Ext.form.field.Base</a>.</p>
<p>The first step is to make the form aware of Model validations. Since we really only care about this when the Model data is loaded to the form via <strong>loadRecord()</strong>, we can start by overriding this method like so:</p>
<pre>Ext.override(Ext.form.Basic, {
    loadRecord: function(record) {
        this._record = record;
        <strong>this.setModelValidations(record.validations);</strong>
        return this.setValues(record.data);
    },
    setModelValidations: function(validations) {
        var fields = this.getFields(), i;
        for(i=0;i&lt;validations.length;i++) {
            if(fields.map[validations[i].field]) {
                fields.map[validations[i].field].setModelFieldValidation(validations[i])
            }
        }
    }
})</pre>
<p>When loadRecord() is invoked, we pass the record to a new custom method, setModelValidations(). This custom method will iterate over the <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.validations">validations object</a> of the specified Model, and will invoke the setModelFieldValidation() method of any form field it finds whose mapping matches that of the Model validation.</p>
<p>The next override is on the base definition for form fields, and looks like so:</p>
<pre>Ext.override(Ext.form.field.Base, {
    setModelFieldValidation: function(validation) {
        this.modelValidations = Ext.isArray(this.modelValidations) ? this.modelValidations : [];
        this.modelValidations.push(validation);
    },
    getModelErrors: function(value) {
        var errors      = Ext.create('Ext.data.Errors'),
            validations = this.modelValidations,
            validators  = Ext.data.validations,
            length, validation, field, valid, type, i;

        if (validations) {
            length = validations.length;

            for (i = 0; i &lt; length; i++) {
                validation = validations[i];
                field = validation.field || validation.name;
                type  = validation.type;
                valid = validators[type](validation, value);

                if (!valid) {
                    errors.add({
                        field  : field,
                        message: validation.message || validators[type + 'Message']
                    });
                }
            }
        }
        return errors;
    },
    validateValue: function(value) {
        var me = this,
            errors = me.getErrors(value),
            modelErrors = me.getModelErrors(value),
            isValid = Ext.isEmpty(errors) <strong>&amp;&amp; modelErrors.isValid()</strong>;
        if (!me.preventMark) {
            if (isValid) {
                me.clearInvalid();
            }
            else {
                <strong>if(!modelErrors.isValid()) { modelErrors.each(function() { errors.push(this.message); }) }</strong>
                me.markInvalid(errors);
            }
        }
        return isValid;
    }
})</pre>
<p>There&#8217;s a lot going on here, so let&#8217;s go method by method.</p>
<p><strong>setModelFieldValidation()</strong>: This is method that is called from the Form&#8217;s setModelValidations() method, and it simply adds a new property to the instance of the form field (modelValidations). This modelValidations is an array which will store any Model-level validations which have been configured for the Model field which matches this form field&#8217;s &#8220;name&#8221;.</p>
<p><strong>getModelErrors()</strong>: This method is almost identical to the Model&#8217;s getErrors() method. The primary difference is that instead of iterating over every validation defined for the Model, this method only iterates over the Model validations which have been assigned to this form field (via setModelFieldValidations()).</p>
<p><strong>validateValue()</strong>: This is an override of the field&#8217;s existing validateValue() method, which is invoked everything a validation occurs. The only additions are to add the Model validation to the check for whether the form &#8220;isValid&#8221;, as well as a short section to append the model validation error messages to the main &#8220;errors&#8221; array (which is ultimately used for communicating the form&#8217;s validation errors to the user).</p>
<h2>Demo and Source</h2>
<p>If you&#8217;d like to see this in action, <a href="http://existdissolve.com/demos/validations/">check out the demo</a>. If you&#8217;d like to see the full source for this mini-app, <a href="https://github.com/existdissolve/ExtJS.4.Playground/tree/master/playground/validations">grab it from GitHub</a>.</p>
<h2>Wrapping Up</h2>
<p>In all honesty, I&#8217;m not sure how practical this approach actually is, or whether you&#8217;d actually want to forge this relationship between the form and model validations. But regardless of the practicality, I think it does, at the very least, demonstrate precisely how stupid simple it is to extend ExtJS to do pretty much whatever you want it to do. And notwithstanding the usefulness of this particular example, this extensibility is precisely why I love this framework.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2012/04/extjs-4-applying-model-validations-to-forms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Quick Thoughts on Sencha Architect 2</title>
		<link>http://existdissolve.com/2012/04/quick-thoughts-on-sencha-architect-2/</link>
		<comments>http://existdissolve.com/2012/04/quick-thoughts-on-sencha-architect-2/#comments</comments>
		<pubDate>Sat, 21 Apr 2012 03:11:42 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Sencha Touch]]></category>
		<category><![CDATA[Architect 2]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2395</guid>
		<description><![CDATA[A few days ago, Sencha rolled out Sencha Architect 2, the major overhaul and rebranding of what was formerly Sencha Designer. You can check out the release blog post to get the low-down on all the new features. When I saw the news about the release, I have to say I was a bit hesitant&#8230;]]></description>
			<content:encoded><![CDATA[<p>A few days ago, Sencha rolled out <a href="http://www.sencha.com/products/architect/">Sencha Architect 2</a>, the major overhaul and rebranding of what was formerly Sencha Designer. You can check out the <a href="http://www.sencha.com/blog/sencha-architect-html5-app-builder-for-touch-and-ext-js/">release blog post</a> to get the low-down on all the new features.</p>
<p>When I saw the news about the release, I have to say I was a bit hesitant to look much further. I&#8217;ve tried Sencha Designer several times in the past, and I&#8217;ve been somewhat disappointed with it. Sure, it was great for laying out apps, but when you actually needed to *code*, it was lackluster at best. But even worse, I found it to be very buggy; it would crash at random times, and overall I found the process of trying to mockup an app to be more frustrating than anything else.</p>
<p>So initially, I wasn&#8217;t planning on even trying out the newest iteration. But then I noticed that one of the biggest additions to the product is  support for creating a full ExtJS or Touch app&#8211;not just the UI. I felt I had to take a closer look, and I&#8217;m glad I did.</p>
<h2>UI</h2>
<p>Out of the box, Architect 2 is <em><strong>worlds better</strong></em> than its previous iterations. The interface is slick and responsive, and the way the UI is organized makes the process of laying out and configuring components feel much more intuitive. One especially nice feature is that in the &#8220;Property&#8221; panel, you can toggle between commonly used configurations and the comprehensive list. Additionally, the configuration options are nicely grouped by inheritance, so you know precisely where your configs are being applied.</p>
<h2>Application Flow</h2>
<p>The coolest part of Architect 2 (to me) is that you can now *really* build applications with it. If you drink the MVC architecture Kool-Aid (and you should!), Architect 2 makes it very simple to build full-on applications.</p>
<p>For example, you can very simply choose to add controllers to your app. Within the controllers, you can customize handlers and custom methods to take care of the all of the business logic of your application.</p>
<h2>Best Practices</h2>
<p>But perhaps the best part of Architect 2 is that in the course of adding components, wiring up event handlers, and just fleshing out your app, you can instantly switch to &#8220;Code&#8221; view to see how the entire app is getting constructed behind the scenes. This gives a much welcome insight into &#8220;best practices&#8221; for developing ExtJS and Touch apps within the MVC architecture&#8211;a much desired feature that many devs have been begging for for quite a while.</p>
<p>I was happy to see that my methodology that was about 95% on point; however, the differences that I&#8217;ve noticed while reviewing the code have filled in some gaps in my understanding, which will simply make building ExtJS and Touch apps that much more fun <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>So&#8230;Will I Buy It?</h2>
<p>At $399, the price tag for Sencha Architect 2 initially feels a little steep. Personally, I would not have paid that much for previous versions, purely based on my lackluster experiences during the trials. However, given how much more solid Architect 2 feels, and based on the fact that it is now geared toward full soup-to-nuts app development, I&#8217;ll have to seriously consider it.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2012/04/quick-thoughts-on-sencha-architect-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ExtJS 4: Querying Records in a Data Store</title>
		<link>http://existdissolve.com/2012/02/extjs-4-querying-records-in-a-data-store/</link>
		<comments>http://existdissolve.com/2012/02/extjs-4-querying-records-in-a-data-store/#comments</comments>
		<pubDate>Sun, 19 Feb 2012 04:29:55 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[Store]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2371</guid>
		<description><![CDATA[As you come to use data stores regularly within ExtJS applications, you&#8217;ll quickly come to realize just how powerful they are. With very little code, you can create robust data repositories that can not only store complex data, but can (perhaps more importantly) drive components within your applications. At some point, however, you&#8217;ll need to&#8230;]]></description>
			<content:encoded><![CDATA[<p>As you come to use <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store">data stores</a> regularly within ExtJS applications, you&#8217;ll quickly come to realize just how powerful they are. With very little code, you can create robust data repositories that can not only store complex data, but can (perhaps more importantly) drive components within your applications.</p>
<p>At some point, however, you&#8217;ll need to retrieve data from your Store in a query-like manner. That is, instead of looking up a record by a known ID or position within the store, you may need to find one or more records based on a search term, a category, or whatever else is required by your app.</p>
<p>Of course, as with everything else, ExtJS makes this pretty simple. Let&#8217;s suppose that we have the following Model:</p>
<pre>Ext.define("MyApp.model.Bookmark", {
     extend: "Ext.data.Model",
     idProperty: "id",
     fields: [
         {name: "id", type: "int"},
         {name: "target", type: "string"},
         {name: "title", type: "string"},
         {name: "category", type: "string"},
         {name: "created", type: "date"}
     ]
});</pre>
<p>Nothing to crazy here. Just a simple model with some standard kinds of fields for storing data, in this case, &#8220;bookmarks.&#8221; Now, let&#8217;s define our data store:</p>
<pre>Ext.define("MyApp.store.Bookmarks", {
    extend: "Ext.data.Store",
    model: "MyApp.model.Bookmark",
    autoLoad: true,
    storeId: 'bookmarks',
    proxy: {
        type: 'localstorage',
        id  : 'myapp-bookmarks'
    }
});</pre>
<p>As with the model, this is very straightforward. We&#8217;ve configured a simple store which happens to have a localStorage proxy (change it if you want&#8211;ExtJS doesn&#8217;t care!).</p>
<h2>Simple Data Lookup</h2>
<p>Ok, so now that we&#8217;re up and running with our model and store, let&#8217;s pretend we&#8217;ve created a simple app to save bookmarks into our data store. As we&#8217;re plugging along, we find that we need to put some kind of tollgate in place to prevent the same bookmark from being entered over and over: after all, having one bookmark to <a href="http://www.youtube.com/watch?v=QFCSXr6qnv4&amp;feature=related">Charlie the Unicorn 2</a> is certainly enough!</p>
<p>How can we prevent this? In our <strong>addBookmark()</strong> method, we can do a simple lookup on our data store to see if a bookmark with the same title already exists. This might look something like so:</p>
<pre>function addBookmark(target,title,category) {
    var store = Ext.data.StoreManager.lookup('bookmarks');
    var match = <strong>store.find('title','title');</strong>
    if(match == -1) {
        ...add the bookmark
    }
}</pre>
<p>In this simple example, we use the store&#8217;s <strong>find()</strong> method to search through the store&#8217;s records. The <strong>find()</strong> method takes two required arguments&#8211;the column to search, and the value to be used in the search&#8211;but has more flexibility for case-sensitivity, partial matches, etc. Based on whether the index of a record in our store is returned, we decide whether or not to add the new data to our store.</p>
<blockquote><p>Of course, if we don&#8217;t care about the index of the record and simply want to get a matched record, we could use <strong>findRecord()</strong> instead. It functions in the same way, but returns a model instance instead of a record index.</p></blockquote>
<h2>More Complex Data Lookup</h2>
<p>The store&#8217;s <strong>find()</strong> and <strong>findRecord()</strong> methods are great if you only need to find matches based on a single data column. What if you need to match on more than one column, though? For example, let&#8217;s say that we want to be able to store bookmarks with the same title as long as they belong to a different category. Obviously, our previous method will not work, since the method will prevent insertions of records with already-existent titles. Nope, we need something a bit more robust. Thankfully, ExtJS data stores have just the ticket: <strong>findBy()</strong>.</p>
<p>The <strong>findBy()</strong> method&#8217;s power lies in the fact that you can specify a custom function that will be executed against every record in the data store. Within this custom function, you can do any manner of checks on the entire data record (not just the value of one column). If the conditions you specify succeed, the method will return the index of the first matching record.</p>
<p>So here&#8217;s what that might look like for our scenario of checking for the uniqueness of both bookmark title AND category:</p>
<pre>function addBookmark(target,title,category) {
    var store = Ext.data.StoreManager.lookup('bookmarks');
    // custom function for finding record with complex criteria
    var match = <strong>store.findBy</strong>(function(record,id) {
        if(record.get('target')==target &amp;&amp; record.get('category')==category) {
            return true;
        }
    });
    if(match == -1) {
        ...add the bookmark
    }
}</pre>
<p>As you can see, the custom function is passed two arguments: the model instance of the currently-evaluated record, and the id of the record. Since we want to check to make sure that the combination of bookmark title and bookmark category are unique, we can simply check the &#8220;title&#8221; and &#8220;category&#8221; values of the would-be-bookmark against each model in our data store. If no match is found, we know the record is unique and we can add it to the data store. Magical <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Wrapping Up</h2>
<p>Obviously, the example provided above is very simple; however, I hope it shows just how easy it is to not only query data from a data store, but moreover to create custom functions to apply more complex query logic to the data in your stores.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2012/02/extjs-4-querying-records-in-a-data-store/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ColdFusion Queries to ExtJS Data Models</title>
		<link>http://existdissolve.com/2012/01/coldfusion-queries-to-extjs-data-models/</link>
		<comments>http://existdissolve.com/2012/01/coldfusion-queries-to-extjs-data-models/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 13:55:09 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Model]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2312</guid>
		<description><![CDATA[I love data Models in ExtJS. They are extremely simple to use, but are amazingly powerful for driving robust JavaScript applications. In fact, I&#8217;ve gotten to the point where I use them in just about everything I do, and they are fast becoming an indispensible part of my JavaScript development approach. A big part of&#8230;]]></description>
			<content:encoded><![CDATA[<p>I love data Models in ExtJS. They are extremely simple to use, but are amazingly powerful for driving robust JavaScript applications. In fact, I&#8217;ve gotten to the point where I use them in just about everything I do, and they are fast becoming an indispensible part of my JavaScript development approach.</p>
<p>A big part of the appeal of ExtJS data Models is their flexibility. While some data &#8220;plugins&#8221; in other JS frameworks certainly allow you mimic some of the behaviors of a data model, ExtJS&#8217; data Model wins hands down because of its extreme flexibility. With a ExtJS <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model">Model</a>, you can quickly and easily create powerful definitions of data objects (fields, data types, associations, validations, etc.) in your application. These models can then in turn be used to craft a data <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store">Store</a>, which can themselves be plugged into many of ExtJS&#8217; data components (DataView, Grid, Chart). What you end up with is a super-powerful, deeply-data-driven application in a ridiculously small number of lines of code.</p>
<p>Of course, the perfect complement to the simplicity and grace of ExtJS&#8217;s data Model is to &#8220;feed&#8221; it using ColdFusion. Below, I&#8217;ll outline how to retrieve data from CF, as well an extremely easy way (there are obviously more!) to format data from a ColdFusion query directly into an ExtJS data Model.</p>
<blockquote><p><strong>Note: For these examples, I am using ColdFusion 9 and ExtJS 4.0.7</strong></p></blockquote>
<h2>ExtJS Models</h2>
<p>As mentioned above, the ExtJS data Model allows you to create pretty powerful&#8211;and flexible&#8211;definitions for data objects in your application. The beautiful part about this is that you can create a Model out of pretty much any data structure that is presented to your application. This allows you to spend your time making your JavaScript application work the way you want it to, without being enslaved to a particular requirement for data formatting (or type, for that matter). So whether you&#8217;re consuming XML, JSON, JSONP, etc., the ExtJS Model is flexible and configurable enough to normalize the incoming data structure into what you ultimately want (and need) your data objects to be for your application.</p>
<h2>ColdFusion Query to JSON</h2>
<p>How does this relate to ColdFusion? Well, let&#8217;s say that you have an existing, remotely-accessible component that returns a query result. In ColdFusion 8 and above, you can specify the &#8220;returnformat=json&#8221; argument in your method invocation, and ColdFusion wil serialize the query object into a JSON-formatted string, and return it to your JavaScript application.</p>
<pre>remote any function getqueryarrays() {
    fauxquery = querynew('id,name,age');
    queryaddrow(fauxquery,4);
    querysetcell(fauxquery,"id","1",1);
    querysetcell(fauxquery,"name","Joel",1);
    querysetcell(fauxquery,"age","31",1);
    querysetcell(fauxquery,"id","2",2);
    querysetcell(fauxquery,"name","Jason",2);
    querysetcell(fauxquery,"age","31",2);
    querysetcell(fauxquery,"id","3",3);
    querysetcell(fauxquery,"name","Godzilla",3);
    querysetcell(fauxquery,"age","100000",3);
    querysetcell(fauxquery,"id","4",4);
    querysetcell(fauxquery,"name","Batman",4);
    querysetcell(fauxquery,"age","0",4);
    return fauxquery;
}</pre>
<p>The one downside of this approach is that you don&#8217;t have a lot of control over how ColdFusion formats the JSON that it returns. It looks something like this:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2012/01/array.png"><img class="size-full wp-image-2316" style="display: block;" title="array" src="http://existdissolve.com/wp-content/uploads/2012/01/array.png" alt="" width="389" height="561" /></a></p>
<p>As you can see, ColdFusion&#8217;s JSON-encoding has done a few things:</p>
<ul>
<li>To represent the data, it has created two arrays: one for the column definitions, and one for the data. I would prefer an array of objects, but this is CF&#8217;s default behavior&#8230;</li>
<li>Perhaps worse, all of the &#8220;keys&#8221; have been uppercased, regardless of the original case of the columns</li>
</ul>
<p>In other JS libraries, you might have to do some pre-processing of the JSON in order to get the data into something more like an array of structures, and/or even re-work the casing on the keys (or modify the requirements in your app to account for the casing). This all, of course, assumes that you have control over the source generating the JSON. Good luck if you don&#8217;t!</p>
<h2>Making the Model</h2>
<p>With ExtJS&#8217;s data Model, the JSON formatting&#8211;and even the ultimate structure of the source data&#8211;just doesn&#8217;t matter. The Model is flexible enough to adapt, and you can easily configure it to consume just about any incoming structure/format that you can think of.</p>
<p>Here&#8217;s what we can do for our example data:</p>
<pre>Ext.define('Person', {
    extend: 'Ext.data.Model',
    fields: [
        {name:"ID", type:'int'},
        {name:"NAME", type:"string"},
        {name:"AGE", type:"number"}
    ],
    proxy: {
        type: 'ajax',
        url: 'remote.cfc?method=getqueryarrays&amp;returnformat=json',
        reader: {
             type: 'array',
             root: 'DATA'
        }
    }
})</pre>
<p>Seriously, it&#8217;s that simple. We just tell the Model that we&#8217;d like to define a data object with a certain number of fields, and it&#8217;s smart enough to automatically find and create an association with the incoming data. Here&#8217;s how we did it:</p>
<ul>
<li>The &#8220;fields&#8221; config option allows us to tell ExtJS what we want our data object to look like. Notice that in this example, the &#8220;name&#8221; attribute is upper-case. This matches the upper-case keys being returned from CF.</li>
<li>The &#8220;proxy&#8221; config allows us to tell the Model how we&#8217;ll retrieve the data that will build the Model. In this case, we&#8217;re using the <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Ajax">AjaxProxy.</a></li>
<li>In the proxy, we&#8217;ve also defined a &#8220;reader.&#8221; This is where the flexibility really comes into play. For the reader type, &#8220;array&#8221; has been specified. This tells ExtJS, at the very least, that our data is in an array format. Next, we&#8217;ve specified a &#8220;root&#8221; of &#8220;DATA.&#8221; This tell ExtJS that the &#8220;DATA&#8221; array will contain the values for the field definitions that we&#8217;ve already created.</li>
</ul>
<p>And with that, our Model is complete. We can now hook this up to a data store, and we&#8217;ll be able to use the store on any number of data-driven ExtJS components.</p>
<h2>A Bit of Tweaking</h2>
<p>Even though that&#8217;s pretty simple, we&#8217;re still a bit tied to the formatting that ColdFusion has returned&#8211;after all, we used the uppercase column names in our field definitions. But what if we don&#8217;t want uppercase field definitions in our Model?</p>
<p>While we can certainly leave it as is, the ExtJS Model allows us to alternatively map field definitions using the &#8220;mapping&#8221; attribute. For the <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Array">ArrayReader</a>, the mapping can be the position in the data structure, rather than the explicit field name. So with just a slight modification, we can easily map our fields as before, but also create arbitrary field names in our Model field definitions:</p>
<pre>Ext.define('Person', {   
     extend: 'Ext.data.Model',   
     fields: [       
        {name:"theid", type:'int',mapping:0},       
        {name:"myname", type:"string",mapping:1},       
        {name:"myage", type:"number",mapping:2}   
     ]
})</pre>
<h2>Wrapping Up</h2>
<p>As we&#8217;ve, ExtJS&#8217;s data Model is an extremely powerful and versatile way of creating robust data objects for JavaScript applications. Not only do they serve as a great foundation for ExtJS&#8217; data-driven components, but they (perhaps more importantly) are flexible enough to suit just about any requirement for incoming data. So instead of having to craft your application around the arbitrary data definitions which come from systems over which you may not have any control, you can easily leverage ExtJS data Models to take back the reins and define data objects based on the needs of your application alone. Pretty awesome <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2012/01/coldfusion-queries-to-extjs-data-models/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>ExtJS 4: Filtering on Multiple Fields</title>
		<link>http://existdissolve.com/2011/11/extjs-4-filtering-on-multiple-fields/</link>
		<comments>http://existdissolve.com/2011/11/extjs-4-filtering-on-multiple-fields/#comments</comments>
		<pubDate>Wed, 23 Nov 2011 06:19:24 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Data Store]]></category>
		<category><![CDATA[ExtJS 4]]></category>
		<category><![CDATA[Filter]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2294</guid>
		<description><![CDATA[Filtering ExtJS data stores is stupid-simple. When filtering, you have 2 main options: Filtering on a property (e.g., &#8220;field&#8221;) Filtering with a custom function So let&#8217;s take a quick look at each one of these. First, here&#8217;s our Model and Store: Ext.define('Person', { extend: 'Ext.data.Model', idProperty: 'id', fields: [ {'firstname', type:'string'}, {'middlename', type: 'string'}, {'lastname',&#8230;]]></description>
			<content:encoded><![CDATA[<p>Filtering ExtJS data stores is stupid-simple. When filtering, you have 2 main options:</p>
<ul>
<li>Filtering on a property (e.g., &#8220;field&#8221;)</li>
<li>Filtering with a custom function</li>
</ul>
<div>So let&#8217;s take a quick look at each one of these.</div>
<div>First, here&#8217;s our <strong><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model">Model</a></strong> and <strong><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store">Store</a></strong>:</div>
<pre>Ext.define('Person', {
    extend: 'Ext.data.Model',
    idProperty: 'id',
    fields: [
         {'firstname', type:'string'},
         {'middlename', type: 'string'},
         {'lastname', type: 'string'}
    ]
});</pre>
<pre>Ext.create('Ext.data.Store', {
    autoLoad: true,
    model: 'Person',
    storeId: 'PersonStore',
    proxy: {
         type: 'ajax',
         url: 'myurl.json',
         reader: {
              type: 'json',
              root: 'people'
         }
    }
});</pre>
<div>Ok, now that we have those set up, let&#8217;s say that we want to filter our results to only those people whose last name contains &#8220;son&#8221; (like &#8220;Watson&#8221;). Using the property filter, we can do this very simply:</div>
<div>
<pre>var store = Ext.data.StoreManager.lookup('PersonStore');
var peoplefilter = new Ext.util.Filter({
     property: 'lastname',
     value: 'son',
     anyMatch: true,
     caseSensitive: false,
     root: 'data'
 });
 store.filter(peoplefilter);</pre>
<p>Nothing to it, right? There are two important parts here. First, for &#8220;property&#8221;, we are simply specifying the field in our Model which we want to filter on&#8230;in this case, &#8220;lastname.&#8221; Second, we specify that we want the filter to look at the &#8220;data&#8221; object of each record&#8211;otherwise, it will fail miserably <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>For simple filtering, using the &#8220;property&#8221; method will get you by pretty good. For more advanced filtering, however, you&#8217;ll need a filter function. A filter function is simply what it sounds like&#8211;a custom function that is run against each record. If the function returns true, the record is included in the results, and is excluded otherwise.</p>
<p>So let&#8217;s say that we want to only return people whose last names <strong><em>begin</em></strong> with &#8220;Mc&#8221;. Our filter function might look like this:</p>
<pre>var store = Ext.data.StoreManager.lookup('PersonStore');
var peoplefilter = new Ext.util.Filter({
    filterFn: function(item) {
        return item.data.lastname.substr(0, 2)=='Mc' ? true : false
    }
});</pre>
</div>
<p>While a little different than using the property method, filterFn is very easy to use. You can simply do custom processing on each item, and determine (via returning true or false) whether the record should be part of the filtered set or not. Pretty simple.</p>
<h2>Passing Multiple Fields to the Property Filter</h2>
<p>Now consider this: you have a larger set of fields in your model, and you want to do something of a wild card search against a number of fields in your model. How would you accomplish this?</p>
<p>Unfortunately, the property filter does not out-of-the-box support passing multiple fields. True enough, you could add 1 filter for each field, but this would leave you with something of an<strong> X AND Y AND Z</strong> result, instead of the desired <strong>X OR Y OR Z</strong> result. You could, of course, figure all of this out in a custom filter function. Here&#8217;s an example of that:</p>
<div>
<pre>var searchfilter = new Ext.util.Filter({
     filterFn: function(item){
         var searchtest,fnmatch,mnmatch,lnmatch;
         var escapere = Ext.String.escapeRegex;
         searchtest = new RegExp(escapere(search), 'i');
         // check match on first name
         fnmatch = searchtest.test(item.data.firstname);
         // check match on middelname
         mnmatch = searchtest.test(item.data.middlename);
         // check match on name
         lnmatch = searchtest.test(item.data.lastname);
         // if any of the fields matched, return true, which will include  record in filtered set
         if(fnmatch || mnmatch || lnmatch) {
             return true;
         }
         // otherwise, return false, which will exclude record from filtered set
         else {
              return false;
         }
    }
})</pre>
</div>
<p>While not particularly pretty, it works. The main problem is that it more or less duplicates what the property filter is already doing, just a in a bit clunkier way. So instead of doing this, a better approach might be to override the default implementation of <strong><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.util.Filter">Ext.util.Filter</a></strong>. Instead of only allowing for a single property to be evaluated, we&#8217;ll beef it up a bit to accept either an array or string of properties.</p>
<div>
<pre>Ext.override(Ext.util.Filter,{
    createFilterFn: function() {
        var me       = this,
            matcher  = me.createValueMatcher(),
            property = !Ext.isArray(me.property) ? me.property.split(',') : me.property
        return function(item) {
            var hasmatch = false;
            for(var i=0;i&lt;property.length;i++) {
                if(matcher.test(me.getRoot.call(me, item)[property[i]])) {
                    hasmatch=true;
                    break;
                }
            }
            return matcher === null ? value === null : hasmatch;
       };
    }
})</pre>
<p>This is a bit cleaner, IMO. Plus, if we ever need to pass multiple fields to test again, we&#8217;ve already got this in place to handle it. Finally, if you compare this to the original, you&#8217;ll notice that very little has been changed, and that it&#8217;s been designed to work agnostic of whether a single or multiple properties are passed.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/11/extjs-4-filtering-on-multiple-fields/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ExtJS 4 Theming: Custom UIs</title>
		<link>http://existdissolve.com/2011/09/extjs-4-theming-custom-uis/</link>
		<comments>http://existdissolve.com/2011/09/extjs-4-theming-custom-uis/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 03:32:06 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[ExtJS 4]]></category>
		<category><![CDATA[theming]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2262</guid>
		<description><![CDATA[In a previous post, I walked through the simple process of creating a custom UI for a toolbar in Sencha Touch. Since theming in Sencha Touch and ExtJS 4 are extremely similar, I thought I&#8217;d walk through the same process, but with an ExtJS 4 flair. In fact, the last post that I wrote was&#8230;]]></description>
			<content:encoded><![CDATA[<p>In a previous post, I walked through the simple process of <a title="Sencha Touch Theming: Custom UIs" href="http://existdissolve.com/2011/09/sencha-touch-theming-custom-uis/">creating a custom UI for a toolbar in Sencha Touch</a>. Since theming in Sencha Touch and ExtJS 4 are extremely similar, I thought I&#8217;d walk through the same process, but with an ExtJS 4 flair.</p>
<p>In fact, <a title="ExtJS 4 Theming: Getting This Thing to Go" href="http://existdissolve.com/2011/09/extjs-4-theming-getting-this-thing-to-go/">the last post that I wrote</a> was meant to be this one. However, as I worked through the process of creating a custom UI, I found that the setup of Compass compilation for ExtJS 4 might have some *gotchas* that could trip people up (like me), so I decided to start from the beginning, get a solid foundation, and now move on to the actual fun stuff.</p>
<p>Ok? Good? On we go!</p>
<h2>What We&#8217;re Going to Make</h2>
<p>In this walkthrough, we&#8217;re going to try to accomplish a few things.</p>
<p><strong>Objective #1:</strong> I want to show how it&#8217;s perfectly possible (maybe preferable?) to mix custom UIs with the stylesheets/images/etc. of the &#8220;default&#8221; ExtJS 4 theme. In this particular example, we&#8217;re going to create a custom Ext.ProgressBar UI.</p>
<p><strong>Objective #2:</strong> We&#8217;re also going to create a custom stylesheet that produces only the minimum of what we need for the &#8220;application&#8221; we&#8217;re going to build. So instead of having a monster ext-all.css file that includes ALL the styles for the entire library, we&#8217;re going to pare down our final stylesheet to only the bare bones of what we need.</p>
<p><strong>Objective #3:</strong> We&#8217;re going to use the SDK&#8217;s &#8220;slice&#8221; tool to create &#8220;backup&#8221; images for old, crappy browsers that don&#8217;t support CSS3 goodness like background gradients and borde-radius.</p>
<p>BTW, I want to be completely up front about this. Nothing I&#8217;m doing here is &#8220;new&#8221; to me. The basic structure of what we&#8217;ll be doing is shamelessly stolen from the <a href="http://www.sencha.com/learn/theming/">Theming Guide</a> on Sencha&#8217;s website. I wanted to walk through the process, though, a bit more in depth with screenshots, code snippets, and real examples, just so any trip-ups can be explained and dealt with along the way.</p>
<h2>Let&#8217;s Get Started</h2>
<blockquote><p>In what follows, I&#8217;ll be using the structure that we setup in the <a title="ExtJS 4 Theming: Getting This Thing to Go" href="http://existdissolve.com/2011/09/extjs-4-theming-getting-this-thing-to-go/">last post on this subject</a>. Obviously, you can flex it to suit your needs; however, if you want to follow along step-by-step, be sure to take care of that first. If you&#8217;d like some source code, <a href="https://github.com/existdissolve/ExtJS.4.Playground">grab it on GitHub</a>.</p></blockquote>
<p>Before we start creating our custom UI, let&#8217;s build our &#8220;app.&#8221; First, let&#8217;s create an HTML file in the root of my project (playground). Now, let&#8217;s create a JavaScript file that will house our app&#8217;s code.</p>
<p>Here&#8217;s the JS code:</p>
<p><strong>playground/js/progress.js</strong></p>
<pre>Ext.onReady(function(){
   var pb = Ext.create('Ext.ProgressBar', {
      margin: 50,ui:'default'
   });
   // Wait for 5 seconds, then update the status el (progress bar will auto-reset)
   pb.wait({
      interval: 500, //bar will move fast!
      duration: 50000,
      increment: 15,
      text: "Hi, I've got a custom UI...",
      scope: this,
      fn: function(){
         p.updateText('Done!');
      }
   });
   var pa = Ext.create("Ext.panel.Panel", {
      title: "I'm a regular 'default' UI Panel",
      width: 500,
      items: pb, // put the progressbar in our panel
      floating: true,
      renderTo: Ext.getBody(),
      closable: true
   })
})</pre>
<p>Here&#8217;s the HTML file:</p>
<p><strong>playground/progress.html</strong></p>
<pre>&lt;html&gt;
   &lt;head&gt;
      &lt;title&gt;Custom Progress Bar UI&lt;/title&gt;
      &lt;link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css"&gt;
      &lt;script type="text/javascript" src="extjs/ext-all.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="js/progress.js"&gt;&lt;/script&gt;
   &lt;/head&gt;
   &lt;body&gt;&lt;/body&gt;
&lt;/html&gt;</pre>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.03.40-PM1.png"><img class="alignnone size-full wp-image-2280" title="Screen Shot 2011-09-28 at 11.03.40 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.03.40-PM1.png" alt="" width="310" height="90" /></a></p>
<p>Once you&#8217;ve got these set up, go ahead a open your file in the browser. You should see a fancy <strong>blue</strong> panel, which contains a fancy <strong>blue</strong> animated progress bar.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.04.30-PM.png"><img class="alignnone size-full wp-image-2270" title="Screen Shot 2011-09-28 at 11.04.30 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.04.30-PM.png" alt="" width="533" height="168" /></a></p>
<p>Now that we have something that&#8217;s working, let&#8217;s get down to styling the darn thing!</p>
<p>Ok, the first thing we&#8217;re going to do is to make a copy of our &#8220;<strong>my-ext-all.scss</strong>&#8221; file with the <strong>playground/extjs/resources/custom</strong> folder. Since we&#8217;re making a custom Ext.ProgressBar UI, I&#8217;m going to call this new file &#8220;<strong>progress.scss</strong>&#8221; (if you can&#8217;t tell, I&#8217;m a sucker for originality). Since our config.rb file was working as expected in our last walkthrough, it&#8217;s fine how it is; no need for us to mess with it anymore.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.05.21-PM.png"><img class="alignnone size-full wp-image-2269" title="Screen Shot 2011-09-28 at 11.05.21 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.05.21-PM.png" alt="" width="310" height="190" /></a></p>
<p>Now, open up <strong>progress.scss.</strong> At the very top, you&#8217;ll see a variable called <strong>$include-default.</strong> If it&#8217;s not already, set it to <em><strong>false</strong></em>. This tells the compiler to NOT include the entire all components in our final .css file. Also, setting this to false will allow us more granularly specify exactly what components we want to include (see Objective #2 above).</p>
<p>Moving on down the file, we&#8217;ll come to a section that has a list of all the components. It should look something like this:</p>
<pre>@include extjs-boundlist;
@include extjs-button;
@include extjs-btn-group;
@include extjs-datepicker;
@include extjs-colorpicker;
@include extjs-menu;
@include extjs-grid;
@include extjs-form;
   @include extjs-form-field;
   @include extjs-form-fieldset;
   @include extjs-form-checkboxfield;
   @include extjs-form-checkboxgroup;
   @include extjs-form-triggerfield;
   @include extjs-form-htmleditor;
@include extjs-panel;
@include extjs-qtip;
@include extjs-slider;
@include extjs-progress;
@include extjs-toolbar;
@include extjs-window;
@include extjs-messagebox;
@include extjs-tabbar;
@include extjs-tab;
@include extjs-tree;
@include extjs-drawcomponent;
@include extjs-viewport;</pre>
<p>If we leave this as is, the compiler is going to pull in all of the style rules for these components into our stylesheet. However, since we&#8217;re only using 2 of them (panel and progress bar), let&#8217;s get rid of the others.</p>
<p>The final list should look like this:</p>
<pre>@include extjs-panel;
@include extjs-progress;</pre>
<p>Awesome. Ok, the final line in our progress.scss file is the variable <strong>$relative-image-paths-for-uis</strong>, and is set to true. I&#8217;ll leave the note for you to read, but let&#8217;s leave its value as <em><strong>true</strong></em>.</p>
<p>Excellent. So these slight modifications, our progress.scss file looks like this:</p>
<pre>// Unless you want to include all components, you must set $include-default to false
// IF you set this to true, you can also remove lines 10 to 38 of this file
<strong>$include-default: false;</strong>

<strong>@import 'compass';</strong>
<strong>@import 'ext4/default/all';</strong>

// You may remove any of the following modules that you
// do not use in order to create a smaller css file.
<strong>@include extjs-progress;</strong>
<strong>@include extjs-panel;</strong>

// This line changes the location of your images when creating UIs to be relative instead of within the ExtJS directory.
// You MUST set this to true/string value if you are creating new UIs + supporting legacy browsers.
// This only applies to new UIs. It does not apply to default component images (i.e. when changing $base-color)
// The value can either be true, in which case the image path will be "../images/"
// or a string, of where the path is
<strong>$relative-image-path-for-uis: true; // defaults to "../images/" when true</strong></pre>
<p>Before moving on, let&#8217;s go ahead an compile. I want to show that while we haven&#8217;t actually done any style customization yet, we can reduce the size of our CSS file by only including the components we need.</p>
<p>To compile, navigate to the custom folder and execute the compass compile command. Once this completes successfully, you should see a new CSS file in the <strong>playground/extjs/resources/css folder</strong> called <strong>progress.css</strong>.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.05.21-PM.png"><img class="alignnone size-full wp-image-2269" title="Screen Shot 2011-09-28 at 11.05.21 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.05.21-PM.png" alt="" width="310" height="190" /></a></p>
<p>Now go back to your progress.html file and change the stylesheet link to point to this new CSS file. Reload the page. If everything compiled correctly, you shouldn&#8217;t notice any difference. However, if you look at the progress.css file itself, you&#8217;ll notice that it&#8217;s quite a bit lighter than the full ext-all.css. Yay, we did it <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <strong>Objective #2 is complete</strong>!</p>
<h2>Get on with the Custom UI Already!</h2>
<p>Yeah, I know, we&#8217;ve gone through a lot of background stuff. However, I think it&#8217;s important. After all, you don&#8217;t want to spend a bunch of time creating custom UIs if your .scss file&#8217;s basic structure won&#8217;t compile correctly. So I strongly advocate verifying that each step is working correctly before moving on. But since we&#8217;ve already done that, let&#8217;s get to some styling!</p>
<p>As with creating a custom toolbar UI in Sencha Touch, a great place to start with creating our custom ProgressBar UI is to figure out what the &#8220;mixin&#8221; for the ProgressBar UI looks like, what arguments it takes, etc. This will allow us to fully maximize the customization that we make in our custom UI.</p>
<p>To inspect the ProgressBar UI mixin, we can simply navigate to the following:</p>
<ul>
<li><strong>playground/extjs/resources/themes/stylesheets/ext4/default/widgets/_progress-bar.scss</strong></li>
</ul>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-10.08.16-PM.png"><img class="alignnone size-full wp-image-2278" title="Screen Shot 2011-09-28 at 10.08.16 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-10.08.16-PM.png" alt="" width="378" height="563" /></a></p>
<p>On <strong>line 66</strong>, we&#8217;ll see the beginning of the <strong>extjs-progress-ui</strong> mixin. As you can see, this mixing accepts a number of arguments:</p>
<ul>
<li>label (the name of our custom UI)</li>
<li>base-color (the foundation color for the UI)</li>
<li>border-color</li>
<li>background-color</li>
<li>bar-background-color</li>
<li>bar-background-gradient</li>
<li>color-front (the color of text when the progress bar is not behind the text)</li>
<li>color-back (the color of text when the progress bar is behind the text)</li>
</ul>
<p>SImple enough. So let&#8217;s go back to our <strong>progress.scss</strong> file. After the @includes of the progress bar and panel, we can simply include our custom UI via the mixin. Here&#8217;s what my example looks like:</p>
<pre>// set a custom progress base color to use in custom UI
$custom_pb_base_color: #Bfff00;
// here's the custom UI! <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
@include extjs-progress-ui(
   'lime',
   $ui-base-color: $custom_pb_base_color,
   $ui-background-color: $progress-background-color,
   $ui-border-color: adjust-color($custom_pb_base_color, $hue: 0deg, $saturation: -3.08%,       $lightness: -23.725%),
   $ui-bar-background-color: adjust-color($custom_pb_base_color, $hue: 0deg, $saturation: -11.37%, $lightness: 7.451%),
   $ui-color-front: #333333,
   $ui-color-back: #333333
);</pre>
<p>In the above, I&#8217;m creating a new progress bar UI called &#8220;lime.&#8221;  I set a custom variable for the base-color I want to use, and then simply specify the colors that I&#8217;d like for the background, border, text, etc.</p>
<p>Once everything looks good, it&#8217;s time to compile. Now that my newly compiled CSS file has the &#8220;lime&#8221; ui for my progress bar, all that&#8217;s left is to apply the UI to the progress bar itself:</p>
<p><strong>In playground/js/progress.js:</strong></p>
<pre>var p = Ext.create('Ext.ProgressBar', {
      margin: 50,
     <strong> ui: 'lime'</strong>
   });</pre>
<p>Once I save this, I should be able to reload my HTML page, and see a beautiful lime green progress bar inside of the default blue themed panel.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.17.59-PM.png"><img class="alignnone size-full wp-image-2266" title="Screen Shot 2011-09-28 at 11.17.59 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.17.59-PM.png" alt="" width="528" height="176" /></a></p>
<p>Using this approach, we could create as many UIs as we&#8217;d like, simply adding similar snippets to our progress.scss file and recompiling when ready to use them.</p>
<h2>Ah, But We Couldn&#8217;t Get This Far WIthout a Gotcha&#8230;</h2>
<p>Yes, indeed. Even though we&#8217;ve successfully compiled our custom CSS file with a custom progress bar UI, there&#8217;s one slight problem&#8230;depending on how you look at it, at least. What&#8217;s the issue?</p>
<p>Pop open your progress.css file that you just compiled. If you go all the way to the end of it, you&#8217;ll see this style rule:</p>
<p><strong>.x-nlg .x-progress-lime .x-progress-bar{background:url(&#8216;../themes/images/default/progress/progress-lime-bg.gif&#8217;) repeat-x}</strong></p>
<p>Notice the background-image with &#8220;lime&#8221; in its name. Now, if you go to that path, guess what you&#8217;ll find? You&#8217;ll find a <strong>progress-default-bg-gif</strong> file, but no <strong>progress-lime-bg.gif</strong> file. What gives?</p>
<p>Well, because ExtJS is a thoroughly committed cross-browser framework, the theming tools automatically create style rules to accomodate old, crappy browsers like &lt; IE9. So for example, since older versions of IE don&#8217;t support background gradients and rounded corners in pure CSS. ExtJS 4&#8242;s stylesheets achieve the same effect through background images.</p>
<p>Therefore, when you create a custom UI, the compilation automatically provides a rule to a theoretical image that you will create, and even handily names it according to your theme.</p>
<p>At this point, you might feel hoodwinked. After all, who wants to be bothered with creating images for background gradients and rounded corners? Not me, for sure. And if you really don&#8217;t care, just skip it. However, if you need to finish out this process, the SDK fortunately has one more tool that will make this ridiculously easy&#8230;and you&#8217;ll never have to open Photoshop, not even once.</p>
<h2>Sencha Slicing Tool</h2>
<p>Sorry, the Sencha Slicing Tool won&#8217;t give you finely shaved roast beef (I tried&#8230;). However, it will help you create the &#8220;helper&#8221; images to support your theme in outdated browsers. Here&#8217;s how we do it.</p>
<p>The first step is that you have to create a &#8220;manifest&#8221; of your UIs and the components to which they correspond. This basically allows the Slicing Tool to determine precisely which images it needs to create based on the type of component, the parameters of your UI, etc.</p>
<p>The manifest is a simple JSON file. I added mine into the playground/extjs/resources/custom folder, right along side my custom .scss file.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-10.39.02-PM.png"><img class="alignnone size-full wp-image-2277" title="Screen Shot 2011-09-28 at 10.39.02 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-10.39.02-PM.png" alt="" width="308" height="361" /></a></p>
<p>Here&#8217;s what the contents should look like:</p>
<pre>Ext.onReady(function() {
   Ext.manifest = {
      widgets: [
         {
            xtype: 'widget.progressbar',
            ui   : 'lime'
         }
      ]
   };
});</pre>
<p>Nothing to it. We simply define the component&#8217;s xtype, as well as the label of our custom UI that we&#8217;re going to use for it.</p>
<p>If you don&#8217;t know the &#8220;xtype&#8221; for the component you&#8217;re using, the easy way to find out is to look up the component in the documentation. Next to the class&#8217; name, you&#8217;ll see the xtype.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.21.03-PM.png"><img class="alignnone size-full wp-image-2264" title="Screen Shot 2011-09-28 at 11.21.03 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-11.21.03-PM.png" alt="" width="427" height="66" /></a></p>
<p>Now for the fun part. Open up Terminal, and navigate to the root of your project.</p>
<p>Now, we need to execute the proper command with the appropriate arguments in order to allow the SDK to do its magic. First, here&#8217;s the full string I used. Assuming you have the same setup, it should work without issue:</p>
<pre>sencha slice theme -d extjs -c extjs/resources/css/progress.css -o extjs/resources/themes/images/default -m extjs/resources/custom/manifest.json -v</pre>
<p>Here&#8217;s the break down of this:</p>
<ul>
<li><strong>slice theme</strong> : this the command for firing up the Slicing tool</li>
<li><strong>-d extjs</strong> : -d is for the directory of ExtJS. In our case, this is &#8220;extjs&#8221;, relative to our root directory</li>
<li><strong>-c &#8230;progress.css</strong> : -c is for the path to the CSS file which will be used in the Slicing process</li>
<li><strong>-o &#8230;default</strong> : the path to the main &#8220;theme&#8221; images folder. Since our CSS is already pointing to the &#8220;default&#8221; theme&#8217;s images folder, that&#8217;s where we want the new image(s) created by the Slicing tool to go</li>
<li><strong>-m &#8230;manifest.json</strong>: -m is for the path to the manifest.json file we created, which will tell the Slicing tool what kinds of images it needs to be creating, based on the custom UIs that we&#8217;ve specified</li>
<li><strong>-v</strong> : this simply instructs the program to give us a listing of the images that its creating</li>
</ul>
<p>Alright, good to go. Let&#8217;s run the command. You should see something like the following:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-10.53.05-PM.png"><img class="alignnone size-full wp-image-2274" title="Screen Shot 2011-09-28 at 10.53.05 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-10.53.05-PM.png" alt="" width="610" height="198" /></a></p>
<p>As you&#8217;ll notice, the tool has generated a new image, and saved it to the location we specified. If we go back and look now, we&#8217;ll see that we now have two images in our folder.</p>
<p>&#8230;And with that, we&#8217;re done. <strong>Objective #3</strong> complete!</p>
<h2>Wrapping Up</h2>
<p>If you&#8217;ve been following along this and the previous posts on theming ExtJS 4 and Sencha Touch, I hope you&#8217;re catching on to just how powerful the theming possibilities are. Sure, it can take a few minutes to get setup&#8230;but once you are set up, making remarkable changes to your application&#8217;s theme is dead simple. As we&#8217;ve only just scratched the surface of what can be done, I hope you&#8217;ll continue to explore.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/09/extjs-4-theming-custom-uis/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>ExtJS 4 Theming: Getting This Thing to Go</title>
		<link>http://existdissolve.com/2011/09/extjs-4-theming-getting-this-thing-to-go/</link>
		<comments>http://existdissolve.com/2011/09/extjs-4-theming-getting-this-thing-to-go/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 12:17:45 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[ExtJS 4]]></category>
		<category><![CDATA[theming]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2245</guid>
		<description><![CDATA[Recently, I&#8217;ve been concentrating a lot on theming for Sencha Touch. If you&#8217;ve read much of what I&#8217;ve posted, you know that I really love how the framework is put together, and think the SASS-y mode of custom theming is just awesome. Of course, ExtJS 4 has many of the same theming features, and a&#8230;]]></description>
			<content:encoded><![CDATA[<p>Recently, I&#8217;ve been concentrating a lot on theming for Sencha Touch. If you&#8217;ve read much of what I&#8217;ve posted, you know that I really love how the framework is put together, and think the SASS-y mode of custom theming is just awesome.</p>
<p>Of course, ExtJS 4 has many of the same theming features, and a very similar workflow for creating and compiling custom themes. I&#8217;ve been playing around within some theming experiments, and learned some frustrating lessons along the way. So I thought I&#8217;d share, step-by-step, how I set up my environment for successfully compiling custom stylesheets for ExtJS 4&#8230;just in case you&#8217;re having issues <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Getting Started</h2>
<p>First off, I&#8217;m assuming you already have Ruby and the Compass/SASS gem installed. If you don&#8217;t take a few minutes to get that done. For instructions on how to do this, <strong><a href="http://www.sencha.com/learn/theming/">check out this walkthrough</a></strong>.</p>
<blockquote><p><strong>Before breezing on, take a few deep breaths. This is a critical step&#8230;if you don&#8217;t do it right, you have hours of frustration ahead of you.</strong></p></blockquote>
<p>I start off with a blank project (I&#8217;m using Eclipse, so insert whatever terminology you use for your IDE). First, I create the root folder for my project. I&#8217;m calling this one &#8220;playground.&#8221;</p>
<p>With my root folder created, the next step is to create a folder in our project to hold our ExtJS assets. I&#8217;m creating one that&#8217;s creatively named &#8220;<strong>extjs</strong>&#8220;. It doesn&#8217;t really matter what you name it&#8230;just make sure it&#8217;s something you can quickly and repetitively type (more on this later).</p>
<p>Now, we need to add the ExtJS 4 library to our project. If you just downloaded it, you should see something like following in the downloaded folder:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.21.12-PM.png"><img class="size-full wp-image-2257 alignnone" style="display: block;" title="Screen Shot 2011-09-27 at 11.21.12 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.21.12-PM.png" alt="" width="504" height="434" /></a></p>
<p>From this folder, copy, at a minimum, the following:</p>
<ul>
<li><strong>ext-all-debug.js</strong></li>
<li><strong>ext-all.js</strong></li>
<li><strong>resources</strong> (the whole folder&#8230;the whole folder&#8230;the whole folder&#8230;do not fail to copy the whole folder!!)</li>
</ul>
<p>Ok, you copied these, right? Double-check, and when you&#8217;re sure you have EVERYTHING you need, paste them into the &#8220;extjs&#8221; folder within your project.</p>
<h2>Create a Custom Sassy Style Sheet</h2>
<p>Excellent. If you followed along with the steps above, you&#8217;ve got a solid structure, not only for theming, but for creating your ExtJS 4 app in general. Here&#8217;s what my setup looks like:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.22.54-PM.png"><img title="Screen Shot 2011-09-27 at 11.22.54 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.22.54-PM.png" alt="" width="381" height="88" /></a></p>
<p>Now for the fun stuff. While it&#8217;s certainly possible to create a full-on custom &#8220;theme&#8221; for your ExtJS 4 app, the best introduction to theming is creating a custom stylesheet that&#8217;s based on the default style structure that comes baked into ExtJS 4 by default. In this walkthrough, we&#8217;re actually not going to customize anything at all. Rather, we&#8217;re simply going to create our own &#8220;ext-all.css&#8221; file, just with a different name. The idea is that once we&#8217;ve got the process down, we can start customizing without the frustration of set up getting in our way.</p>
<p>So the first thing I like to do is to create a custom folder to store my .scss (sassy cascading style sheet) files. I do this at the following location:</p>
<ul>
<li>playground/extjs/resources/custom/</li>
</ul>
<div><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-12.09.00-AM.png"><img class="alignnone size-full wp-image-2258" title="Screen Shot 2011-09-28 at 12.09.00 AM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-28-at-12.09.00-AM.png" alt="" width="385" height="156" /></a></div>
<p>The next step I take is to copy the helpful .scss template that ExtJS 4 provides. You can find this at the following location:</p>
<ul>
<li><strong>playground/extjs/resources/themes/templates/resources/sass</strong></li>
</ul>
<div><strong><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.24.50-PM.png"><img class="alignnone size-full wp-image-2255" title="Screen Shot 2011-09-27 at 11.24.50 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.24.50-PM.png" alt="" width="381" height="326" /></a><br />
</strong></div>
<p>Take the &#8220;<strong>config.rb</strong>&#8221; and &#8220;<strong>my-ext-theme.scss</strong>&#8221; files, copy them, and paste them into the custom folder we just created. Rename the .scss file to something more relevant&#8230;I&#8217;m going to use &#8220;<strong>my-ext-all.scss</strong>&#8220;.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.25.48-PM.png"><img class="alignnone size-full wp-image-2254" title="Screen Shot 2011-09-27 at 11.25.48 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.25.48-PM.png" alt="" width="380" height="206" /></a></p>
<p>If you open up <strong>my-ext-all.scss</strong>, you&#8217;ll note that there are a few variables being set, and a lot of guidance notes. I&#8217;d encourage you to take a few moments to read through them to being gaining some understanding about what&#8217;s going on.</p>
<h2>Let&#8217;s Compile</h2>
<p>At this point, we&#8217;ve technically created a custom stylesheet for ExtJS 4. All that&#8217;s left is to compile. <a href="http://compass-style.org/help/tutorials/production-css/">Check out Compass&#8217; website</a> if you have no idea what this means. If you <strong><em>don&#8217;t care</em></strong> what it means and just want to compile something, keep reading <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>To compile, first open up Terminal. Navigate to the &#8220;custom&#8221; folder that we created a few steps ago. Here&#8217;s what it looked like for me:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.29.04-PM.png"><img class="alignnone size-full wp-image-2253" title="Screen Shot 2011-09-27 at 11.29.04 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.29.04-PM.png" alt="" width="743" height="58" /></a></p>
<p>Once you&#8217;ve successfully navigated to this folder, simply type &#8220;compass compile.&#8221;</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.29.59-PM.png"><img class="alignnone size-full wp-image-2252" title="Screen Shot 2011-09-27 at 11.29.59 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.29.59-PM.png" alt="" width="744" height="57" /></a></p>
<p><span style="color: #ff0000;"><strong>CRAP!</strong>  <strong>CRAP!  CRAP!</strong></span>  On your first compile, you&#8217;re probably going to see a lot of RED. You might see a bunch of warning messages to the effect that &#8220;Theme image not found&#8230;&#8221;</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.30.31-PM.png"><img class="alignnone size-full wp-image-2251" title="Screen Shot 2011-09-27 at 11.30.31 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.30.31-PM.png" alt="" width="744" height="544" /></a></p>
<p>On the bright side, this process still created a stylesheet, in spite of the errors. If you look in <strong>playground/extjs/resources/css</strong>, you should see a new .css file with the same naming convention as our .scss file: &#8220;<strong>my-ext-all.css</strong>&#8220;. On the not-so-bright-side, if we actually try to use this, it will be broken. Most things will look pretty okay, but important images (tool icons, etc.) will be nowhere to be found. Not great.</p>
<p>Fortunately, this is *relatively* easy to fix.</p>
<p>In your project, navigate to the following file and open it:</p>
<ul>
<li><strong>playground/extjs/resources/themes/lib/utils.rb</strong></li>
</ul>
<div><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.31.55-PM.png"><img class="alignnone size-full wp-image-2250" title="Screen Shot 2011-09-27 at 11.31.55 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.31.55-PM.png" alt="" width="384" height="261" /></a></div>
<p>Two small changes here:</p>
<ul>
<li><strong>Line 44(ish):</strong> Change relative_path = &#8220;../images/&#8221; to relative_path = &#8220;../themes/images/default&#8221; <strong>***</strong></li>
<li><strong>Line 62(ish):</strong> Replace images_path = File.join($ext_path,&#8217;resources&#8217;,'themes&#8217;,'images&#8217;,theme) with images_path = relative_path</li>
</ul>
<p>With these changes made, go delete the &#8220;<strong>my-ext-all.css</strong>&#8221; file (<span style="color: #ff0000;"><strong>NOT THE .SCSS FILE</strong></span>!). Now, recompile. You *shouldn&#8217;t* see any more RED, but simply see a confirmation that the compilation was successful and that your new CSS file was created.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.54.03-PM.png"><img class="alignnone size-full wp-image-2249" title="Screen Shot 2011-09-27 at 11.54.03 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.54.03-PM.png" alt="" width="741" height="48" /></a></p>
<blockquote><p><strong>***</strong> Some walkthroughs will tell you to make a copy of your &#8220;themes/images/default&#8221; folder and place it in the root of &#8220;resources.&#8221; If you use this approach, you won&#8217;t need to make a copy.</p></blockquote>
<p>Now, if we take a peek in our css folder (playground/extjs/resources/css), we should notice a new <strong>my-ext-all.css</strong> file. And if we hook it up to one of our pages, it should display the correct style AND successfully deliver the correct image paths for loading.</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.56.11-PM.png"><img class="alignnone size-full wp-image-2248" title="Screen Shot 2011-09-27 at 11.56.11 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-27-at-11.56.11-PM.png" alt="" width="380" height="327" /></a></p>
<h2>Wrapping Up</h2>
<p>At first glance, it might appear that we didn&#8217;t really accomplish a whole lot. Honestly, in terms of &#8220;producing&#8221; things, we didn&#8217;t&#8230;we merely duplicated what was already a perfectly good stylesheet.</p>
<p>But from a more important perspective, we actually accomplished a lot. Now that we have things wired up correctly, we can really begin digging into customizing our custom style sheet. While we could have certainly jumped right into that from the beginning, believe me, it&#8217;s better to get things wired up first. There&#8217;s nothing more frustrating that staring at error messages for hours on end because you didn&#8217;t take the time to get things set up properly from the start.</p>
<p>So what about customization? In my next post, I&#8217;ll show just how easy it is to begin customizing our stylesheet now that we&#8217;ve got our compilation process worked out.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/09/extjs-4-theming-getting-this-thing-to-go/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Hello 2003, Let&#8217;s Build a Stylesheet Switcher!</title>
		<link>http://existdissolve.com/2011/08/hello-2003-lets-build-a-stylesheet-switcher/</link>
		<comments>http://existdissolve.com/2011/08/hello-2003-lets-build-a-stylesheet-switcher/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 22:25:22 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Stylesheet]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2200</guid>
		<description><![CDATA[Back in the day, stylesheet-switchers were super-cool. I can clearly remember the thrill of creating several &#8220;themes&#8221; for a website, hooking them up to a cookie, and letting the awesome-ness roll. And in a way, they were pretty cool. After all, having the ability to switch the theme of a website did give *some* customizability&#8230;]]></description>
			<content:encoded><![CDATA[<p>Back in the day, stylesheet-switchers were super-cool. I can clearly remember the thrill of creating several &#8220;themes&#8221; for a website, hooking them up to a cookie, and letting the awesome-ness roll. And in a way, they <em><strong>were</strong></em> pretty cool. After all, having the ability to switch the theme of a website did give *some* customizability to your website, even if the rest of the website was horrifically static!</p>
<p>But the big problem with switching stylesheets in the old days was the incredible headache of trying to maintain X-number of iterations of stylesheets. Need to switch the hue of the link colors? Bust out the find and replace, and be sure you don&#8217;t miss any! Want to add a bit of padding to your navigation? Rinse, repeat, and puke. It was burdensome, and prone to many mistakes. I can remember advocating STRONGLY on many occasions to just &#8220;live with&#8221; the current styles, rather than facing down the daunting task of modifying 8 different stylesheets which may or may not have had any comments/guidance/formatting to them (ok, some of that&#8217;s my bad I&#8217;m sure&#8230;).</p>
<p>So because of these frustrations, stylesheet-switching fell out of favor&#8230;at least with me. Too much work for not enough payoff. But those days are behind us now. With <a href="http://sass-lang.com/">SASS</a>, it&#8217;s ridiculously easy to not only create several &#8220;themes&#8221; based on a root stylesheet, but SASS also allows you to get ridiculously complex with variables, mixins, and the like&#8211;all with the end result of minimized maintenance needed when making small or large changes.</p>
<h2>Getting This Thing to Go</h2>
<p>Long story short, I&#8217;m giving stylesheet switching another go. Using SASS, I created my theme variations. It took, oh, about 5 minutes. Done. Next step? Getting my app to &#8220;remember&#8221; the user&#8217;s stylesheet choice. In the old days, I used cookies. How trite! With <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.LocalStorage">ExtJS 4, I can leverage localStorage</a>, and quickly and easily save, modify and retrieve user&#8217;s stylesheet selections.</p>
<p>So with those chores out of the way, my last task was to actually make the &#8220;switch&#8221; happen. Before anything else, I dug up some old code to see what I had done. As expected, it looked something like this.</p>
<p>First, the HTML:</p>
<pre>&lt;link type="text/css" rel="stylesheet" href="ss1.css" /&gt;
&lt;link type="text/css" rel="alternate" href="ss2.css" /&gt;
&lt;link type="text/css" rel="alternate" href="ss3.css" /&gt;
&lt;link type="text/css" rel="alternate" href="ss4.css" /&gt;</pre>
<p>Then the JS (stolen from an excellent, albeit old, article from <a href="http://www.alistapart.com/articles/alternate/">A List Apart</a>:</p>
<pre>function setActiveStyleSheet(title) {
   var i, a, main;
   for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
     if(a.getAttribute("rel").indexOf("style") != -1
        &amp;&amp; a.getAttribute("title")) {
       a.disabled = true;
       if(a.getAttribute("title") == title) a.disabled = false;
     }
   }
}</pre>
<p>So here&#8217;s the thing. This TOTALLY still works. And it works well. There&#8217;s nothing particular &#8220;bad&#8221; about it. Right? If it works, it works, it works. But I wasn&#8217;t quite happy with it. And here&#8217;s why.</p>
<p>This particular method presumes that all the potential stylesheets are loaded when the page initially loads. While this is probably no big deal for relatively small files (heck, it&#8217;s probably not even a big deal for moderately large files&#8230;), what happens when you have 7 or 8 alternate stylesheets that you want to be available? Obviously, you don&#8217;t want to load all those up front, and since you want them standalone, you can&#8217;t smash them altogether into one. So we need a better way.</p>
<p>The First Try</p>
<p>The first thing I tried was to load a single, default stylesheet. Then, whenever the stylesheet selection changed, I simply swapped the &#8220;href&#8221; of the stylesheet link with that of the new stylesheet, like so:</p>
<p>HTML:</p>
<pre>&lt;link type="text/css" rel="stylesheet" href="ss1.css" id="stylesheetswitch" /&gt;</pre>
<p>JavaScript:</p>
<pre>switchstylesheet: function(sheet) {
    var base = "resources/css/"
    Ext.get("stylesheetswitch").set({href:base+sheet+".css"});
}</pre>
<p>Nothing to it, and it worked&#8230;sort of. In Chrome and Safari, it seemed to work pretty smoothly. The switch from stylesheet to stylesheet was seamless. However, when I tried it in Firefox, I noticed a pretty gnarly &#8220;flicker&#8221; in the interim between the old sheet shoving off and the new one being loaded. By &#8220;flicker,&#8221; I mean, of course, that my page lost all CSS structuring. Complete mayhem.</p>
<p>So obviously this wasn&#8217;t going to work. I flirted with the idea of masking the entire page for a set duration (maybe 300 milliseconds) to hide the flicker, but it just felt hacky.</p>
<h2>The Second Try</h2>
<p>For my second (and successful try), I decided to take a completely different approach, one that is actually a cousin of the &#8220;old-school&#8221; way of switching stylesheets. In my version, though, I take a slightly different approach. In the &#8220;old&#8221; version, the switch is made from a link with a &#8220;rel&#8221; of &#8220;stylesheet&#8221; to one with the &#8220;rel&#8221; of &#8220;alternate.&#8221; Mine does the same thing. The difference, however, is that instead of pre-loading all my stylesheets on the initial page load, I only load the one&#8217;s I need upfront. Then, when a stylesheet that hasn&#8217;t been loaded is requested, I simply load it to the page and then do the normal stylesheet switch.</p>
<p>Here&#8217;s my approach:</p>
<p>HTML:</p>
<pre>&lt;link rel="stylesheet" type="text/css" href="resources/css/ext-all-gray.css" id="ss-gray"&gt;</pre>
<p>JavaScript:</p>
<pre>switchstylesheet: function(sheet) {
    var base = "resources/css/";
    if(Ext.get("ss-" + sheet)) {
        Ext.select("link[id!=ss-"+sheet+"]").each(function(){
            this.set({rel:"alternate"});
        });
        Ext.get("ss-"+sheet).set({rel:"stylesheet"});
    }
    else {
        var dh = Ext.core.DomHelper;
        dh.append("header",{tag:"link",rel:"stylesheet",type:"text/css",href:base+"ext-all-"+sheet+".css",id:"ss-"+sheet});
    }
}</pre>
<p>First, you&#8217;ll notice that I gave my &#8220;default&#8221; stylesheet a unique id (&#8220;ss-&#8221; + &#8216;theme&#8217; name). In my switch function, I do a few things. First of all, I check the DOM to see if a stylesheet with the expected &#8220;theme&#8221; id has already been loaded. If it has, I first loop over all the other stylesheets, setting their &#8220;rel&#8221; to alternate, and finish by setting the selected stylesheet&#8217;s &#8220;rel&#8221; to stylesheet.</p>
<p>If the selected stylesheet has not been loaded, however, I do something different. Using ExtJS&#8217; excellent <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.DomHelper">DomHelper</a>, I create new link tag on the fly, append it to my &lt;head&gt; element, and the switch is made.</p>
<h2>Wrapping Up</h2>
<p>So that&#8217;s about it. A new approach (at least for me) to an old issue. The thing I really like about this method is that it keeps the CSS file footprint small on page load, but also bypasses the &#8220;flicker&#8221; issues of manipulating a single &lt;link&gt; tag&#8217;s href attribute. Even though it&#8217;s possible [likely?] that every single stylesheet will eventually be loaded to the page (for example, if the user is browsing through all of them to find the perfect mood), this approach distributes the &#8220;load&#8221; of those stylesheets through the lifetime of the application, rather than forcing the hit right off the bat.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/08/hello-2003-lets-build-a-stylesheet-switcher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExtJS 4: My First Build</title>
		<link>http://existdissolve.com/2011/08/extjs-4-my-first-build/</link>
		<comments>http://existdissolve.com/2011/08/extjs-4-my-first-build/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 21:30:40 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[.jsb3]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2196</guid>
		<description><![CDATA[One of the really great aspects of ExtJS 4 is the ability to configure how dependencies in your application are loaded, using asynchronous loading, synchronous loading, or a combination of both. This flexibility lets you really dig into detail when debugging, and you are able to file-by-file see where errors are occurring, where processes can be improved, etc. But even&#8230;]]></description>
			<content:encoded><![CDATA[<p>One of the really great aspects of ExtJS 4 is the ability to configure how dependencies in your application are loaded, using asynchronous loading, synchronous loading, or a combination of both. This flexibility lets you really dig into detail when debugging, and you are able to file-by-file see where errors are occurring, where processes can be improved, etc. But even more, you can specify very granularly which files you want&#8211;and need&#8211;while excluding those you don&#8217;t.</p>
<p>Of course, all of this is really meant for your development environment. While it&#8217;s fine to load 70+ individual JavaScript files while working out your app&#8217;s functionality, you *definitely* do not want to impose such a monstrous load on your site&#8217;s actual visitors. This, after all, is why everyone uses <strong>ext-all.js</strong>. It&#8217;s the whole framework, smashed down into a single, minified file. But the problem is that it&#8217;s still the *whole* thing. There are probably a bunch of bits of ExtJS that you don&#8217;t need. This is where the Sencha SDK tool&#8217; can help create a custom build that includes everything you need for your application to run, without the overhead of all the stuff you don&#8217;t.</p>
<p>In what follows, I&#8217;m going to outline my first ExtJS 4 build using the SDK tools. As a disclaimer, this is my first go, so take it with a grain of salt. If I&#8217;ve missed some important bits, or am just plain wrong on any part, please let me know in the comments. And of course, any constructive criticism as to how I can go about this better/more efficiently/etc. is most welcome.</p>
<p>Good? Okay, on we go!</p>
<h2>Getting the SDK Tools Setup</h2>
<p>First things first. Grab a copy of the <a href="http://www.sencha.com/products/sdk-tools/">SDK tools</a> (for this walkthrough, I&#8217;m using v1.2.3). I simply installed them to the default directory. On my Mac, this is <strong>/Applications/SenchaSDKTools-1.2.3</strong>.</p>
<p>Ok, as we move on I&#8217;m going to assume you already have an ExtJS-based application more or less running on your development machine. For me, my application&#8217;s path is like so: <strong>/Applications/sites/gloss/</strong>. In this directory, I have my app structured according to the guidelines outlined in <a href="http://docs.sencha.com/ext-js/4-0/#!/guide/application_architecture">Sencha&#8217;s MVC introduction</a>. I&#8217;m going to assume that you do as well <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Before moving on, here&#8217;s a quick look at the index.html file of my app: you&#8217;ll notice I&#8217;m using the <strong>ext-debug.js</strong> file and my custom <strong>app.js</strong> (per the MVC Architecture recommendations).</p>
<pre>&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Gloss&lt;/title&gt;
    &lt;link rel="stylesheet" type="text/css" href="resources/css/ext-all-gray.css"&gt;
    &lt;script type="text/javascript" src="extjs/ext-debug.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="app.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    ....
&lt;/body&gt;
&lt;/html&gt;</pre>
<h2>Creating the JSB3 File</h2>
<p>The first real step to creating our custom build is to use the Sencha SDK tools to <strong>generate a .jsb3 file</strong>. This will be used to tell the SDK tools precisely which resources (.js files) need to be included/smashed/minified/obfuscated. This file is generated in one step, and the actual build is created in another. There&#8217;s a good reason for this, namely that you can modify the .jsb3 file (if needed) before finalizing the build (more on this later).</p>
<p>To create the .jsb3 file, open up <strong>Terminal.</strong> Navigate to your application&#8217;s root. For me, this looks like:</p>
<pre>cd /Applications/sites/gloss/</pre>
<p>You should now be in your application&#8217;s root folder.</p>
<p>Next, we need to run the Sencha <strong>create</strong> command to generate the .jsb3 file. I&#8217;ll include the command first, then describe it a bit:</p>
<pre>sencha <strong>create</strong> jsb -a <strong>http://127.0.0.1/gloss/index.html</strong> -p app.jsb3</pre>
<p>The most important part, really, is the address in the middle. According to the docs, you can use either the file name relative to your application (e.g., &#8220;index.html&#8221;), or the URL of your application (e.g., &#8220;http://127.0.0.1/gloss/index.html&#8221;). I didn&#8217;t have luck with the relative path, but the full URL worked well for me. Give it a try both ways, and see what result you get.</p>
<p>If you didn&#8217;t run into any errors, you should now see a new file in your application&#8217;s root, based on whatever name you specified in the &#8220;create&#8221; command above (for this example, it&#8217;s simply called <strong>app.jsb3</strong>). If you open it up, you should notice something like the following:</p>
<pre>{
    "projectName": "Project Name",
    "licenseText": "Copyright(c) 2011 Company Name",
    "builds": [
        {
            "name": "All Classes",
            "target": "all-classes.js",
            "options": {
                "debug": true
            },
            "files": [
                {
                    "path": "extjs/src/util/",
                    "name": "Observable.js"
                },
                {
                    "path": "app/controllers/",
                    "name": "MyController.js"
                },
                ....a lot more here....
            ]
        },
        {
            "name": "Application - Production",
            "target": "app-all.js",
            "compress": true,
            "files": [
                {
                    "path": "",
                    "name": "all-classes.js"
                },
                {
                    "path": "",
                    "name": "app.js"
                }
            ]
        }
    ],
    "resources": []
}</pre>
<p>The .jsb3 specifies that two &#8220;builds&#8221; will be created. One will be <strong>all-classes.js</strong>, which will be a smashi-fication of <em><strong>all</strong></em> the needed ExtJS resources, as well as your custom files. This will be a human-readable collection of all the possible ExtJS and custom scripts that your application uses.</p>
<p>The next, <strong>app-all.js</strong>, will be a concatenation of all-classes.js and your main, custom app.js file (or whatever you called it). This file will be the one that you ultimately deploy to production&#8230;but let&#8217;s not get ahead of ourselves.</p>
<p>A few important points here. First, you should take a quick glance through the first &#8220;build&#8221; to ensure that it does, in fact, have both ExtJS files AND your custom application files. If it doesn&#8217;t, there&#8217;s something misconfigured in how your application is setup, and you should fix that before moving forward. Second, you&#8217;ll notice the placeholders for naming your build. Go ahead and fill that out so your smashed files will have good, meaningful documentation on them.</p>
<p>Everything look good? Excellent! Now it&#8217;s time to build some files!</p>
<h2>Building app-all.js</h2>
<p>After verifying that our app.jsb3 file looks correct and filling out the necessary documentation, we&#8217;re now ready to complete the build.</p>
<p>To do that, open Terminal back up again, and make sure that you&#8217;re back at your application&#8217;s root. To create the build, simply enter the following commands:</p>
<pre>sencha <strong>build</strong> -p app.jsb3 -d .</pre>
<p>Simple enough: the &#8220;build&#8221; command grabs the app.jsb3 file we already created, and uses it as a manifest for creating the build files. Once everything completes without error, you should now notice two additional JavaScript files in your application&#8217;s root: <strong>all-classes.js</strong> and <strong>app-all.js</strong>.</p>
<p>Now that the build has completed, you can go into your index.html file and replace <em>ext-debug.js</em> with <strong>ext.js</strong>, and <em>app.js</em> with <strong>app-all.js</strong>. Open up your application, test, and if everything looks good, you should be ready to deploy with your new minified file.</p>
<p>Here&#8217;s what my final index.html file looks like:</p>
<pre>&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Gloss&lt;/title&gt;
    &lt;link rel="stylesheet" type="text/css" href="resources/css/ext-all-gray.css"&gt;
    &lt;script type="text/javascript" src="extjs/ext.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="app-all.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    ....
&lt;/body&gt;
&lt;/html&gt;</pre>
<h2>Something of a Caveat</h2>
<p>While the build worked without error for me, I did notice one issue. When I loaded up my app to test, I still saw a few additional JavaScript files being synchronously loaded. Sure, it wasn&#8217;t the 70+ from before the build, but it was still a handful&#8211;in addition to the main ext.js and app-all.js files.</p>
<p>As I looked closer at *which* files they were, however, I noticed that they seemed to mostly deal with the resources needed for my Viewport. Curious, I opened up my original app.js file, and sure enough, noticed the following:</p>
<pre>Ext.application({
    name: "Gloss",
    appFolder: "app",
    <strong>autoCreateViewport: true</strong>,
    ....
});</pre>
<p>While I&#8217;m not sure I can verify that this is true, it seems like the issue has to do with the &#8220;autoCreateViewport&#8221; setting. Perhaps because of the way that the internals of the dependency negotiator works, it misses some of these files while creating the <strong>.jsb3</strong> file. Your guess is as good as mine.</p>
<p>Fortunately, there is a pretty dang easy way to fix it. I simply opened up Terminal again and re-ran the <strong>.jsb3</strong> <em><strong>creat</strong><strong>e</strong></em> command while leaving the <span style="text-decoration: underline;">app-all.js</span> file set on my index.html page. When the new .jsb3 file was generated, it included only the resources which were missed in the first go. I simply copied the contents of this <strong>.jsb3</strong> file, merged them into my original, and re-ran the build. Voila, no more extra files!</p>
<h2>Wrapping Up</h2>
<p>Overall, I found the build process to be really nice. Notwithstanding the issue which came from how my application is structured, the steps are very straightforward&#8211;it&#8217;s much better than the efforts I&#8217;ve used in the past.</p>
<p>I hope this walkthrough is helpful to someone, and by all means be sure to let me know if there are areas I can improve upon, corrections I can make, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/08/extjs-4-my-first-build/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>ExtJS 4: A Modified Ext.util.History</title>
		<link>http://existdissolve.com/2011/08/extjs-4-a-modified-ext-util-history/</link>
		<comments>http://existdissolve.com/2011/08/extjs-4-a-modified-ext-util-history/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 14:23:08 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Ext.util.History]]></category>
		<category><![CDATA[ExtJS4]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2188</guid>
		<description><![CDATA[I recently implemented Ext.util.History for the first time in a project that I&#8217;m working on. If you&#8217;re not familiar with History, it allows you to &#8220;register arbitrary tokens that signify application history state on navigation actions&#8221;. You can then take these &#8220;tokens&#8221; and use them in your application to display certain views, fire actions, etc.&#8230;]]></description>
			<content:encoded><![CDATA[<p>I recently implemented Ext.util.History for the first time in a project that I&#8217;m working on. If you&#8217;re not familiar with History, it allows you to &#8220;register arbitrary tokens that signify application history state on navigation actions&#8221;. You can then take these &#8220;tokens&#8221; and use them in your application to display certain views, fire actions, etc. when the user uses their browser&#8217;s &#8220;back&#8221; and &#8220;forward&#8221; buttons. In other words, it can help you prevent your 1-page AJAX application from reloading completely when someone accidentally hits the back button. But on a more positive note, it allows your AJAX application to use regular navigation conventions of the browser to control in-application functionality. Pretty cool.</p>
<p>The best part about History, however, is that it is stupid-simple to implement. There are basically 3 steps:</p>
<ol>
<li>Initialize Ext.util.History</li>
<li>Build in the &#8220;token-building&#8221; logic into your application at appropriate places</li>
<li>Define the listener for handling History events.</li>
</ol>
<p>That&#8217;s it. History is not only easy to implement, but it is also pretty unobtrusive&#8211;you can implement it fairly simply into an existing app without completely reworking the whole thing.<br />
There&#8217;s a lot more to History, of course, so be sure to <a href="http://docs.sencha.com/ext-js/4-0/#/api/Ext.util.History">check out the docs</a> and <a href="http://dev.sencha.com/deploy/ext-4.0.2a/examples/history/history.html">Sencha&#8217;s example</a>.</p>
<h2>First, My Example&#8230;</h2>
<p>Before I talk about the limitation I found in History&#8211;and how I overcame it&#8211;let me lay out the flow in my application.<br />
In my app, I have a navigation tree in which each item functions a link to retrieve the &#8220;main page&#8221; data from an external data source. So with each click in the navigation, there is one AJAX request to get data, and the data is then added to the body of a panel in my app.</p>
<p>The idea for History, then, is that I want to tokenize the necessary parameters for my AJAX call, so that when users go &#8220;back&#8221; or &#8220;forward&#8221; in the browser, the AJAX request will be fired for the &#8220;previous&#8221; or &#8220;next&#8221; page, and they&#8217;ll get the appropriate content returned&#8230;just as if they had clicked the link in the navigation tree.</p>
<p>So let&#8217;s walk through how I set this up:</p>
<p>First, I initialize Ext.util.History:</p>
<pre>Ext.require(['Ext.util.History']);
Ext.util.History.init();</pre>
<p>Pretty hard, right? <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Next, I&#8217;ll set up my History &#8220;token&#8221; in the appropriate place. In this example, I&#8217;m placing it the handler for a custom event called &#8220;afterupdate&#8221;&#8211;this event fires after I receive my data back from the AJAX request, as well as after the content of my main body panel has been updated. I put the History tokenization here because if this event fires, I know that I have valid data to tokenize&#8230;</p>
<pre>this.control({
    "maincontent": {
        afterupdate: function(target,type) {
            ...
            // add to real Ext History
            var oldtoken = Ext.util.History.getToken();
            var newtoken = type + ":" + target;
            if(oldtoken === null || oldtoken.search(newtoken) === -1) {
                Ext.History.add(newtoken);
            }
        }
    }
})</pre>
<p>So this is pretty self-explanatory. We first get the old token (retrieved by calling Ext.util.History.getToken()), as well as build our new token. As you can see, the value is completely up to you, so you can be as specific as you want (just be sure to use valid URL characters&#8230;).</p>
<p>Finally, if the old token is not defined or empty string, OR not equal to the new token (e.g., we clicked the same link twice in a row), we execute History&#8217;s add() method.</p>
<p>The last part of this is the listener for the &#8220;change&#8221; event. It&#8217;s here that everything gets pulled together:</p>
<pre>Ext.util.History.on('change', function(token) {
    if (token) {
        var page = token.split(":");
        me.getController("Navigation").loadfromhistory(page[1],page[0]);
    }
});</pre>
<p>If a token exists, we split it on the same delimiter we used when creating the token. With these values, we can then do whatever we want&#8211;such as executing the loadfromhistory() method which will trigger an AJAX request for the specified page.</p>
<h2>&#8230;Then the Limitation</h2>
<p>While this works brilliantly, there is a small limitation, and it&#8217;s simply that the &#8220;change&#8221; event is fired when the browser back/forward buttons are clicked, OR when the add() method is executed. In the context of my application that basically means the following occurs:<br />
<strong></strong></p>
<p><strong>Browser Back/Forward Click:</strong></p>
<ul>
<li>loadfromhistory() method executed (good)</li>
</ul>
<p><strong>add() Method:</strong></p>
<ul>
<li>Original AJAX request executed</li>
<li>Main panel updated</li>
<li>add() method fires &#8211;&gt; triggers History change event</li>
<li>loadfromhistory() method executed (bad)</li>
</ul>
<p>As you can see, when adding a token, I basically get the same AJAX request executed twice. While this doesn&#8217;t hurt anything really (well, unless I didn&#8217;t build my token right&#8230;), it&#8217;s a waste; there&#8217;s no need to make two requests for one set of data.</p>
<p>Unfortunately, out of the box I couldn&#8217;t figure out a way to get around this. There&#8217;s no &#8220;suppressChange&#8221; flag for the add method, and there&#8217;s no additional information that I can key in on within the change event itself to different between these two scenarios.</p>
<p>What&#8217;s more, it doesn&#8217;t *appear* to be bad implementation on my part (I&#8217;ll take correction on that if I&#8217;m off base on this). If you look at the <a href="http://dev.sencha.com/deploy/ext-4.0.2a/examples/history/history.html#main-tabs:tab1:subtab1">example for Ext.util.History</a>, the same behavior occurs: the setActiveTab() method is executed twice when the History add() method is invoked (e.g., when a tab is clicked), but only once when the browser buttons are used.</p>
<h2>The Workaround</h2>
<p>After doing a bit of Googling, and finding some common complaints about the lack of event suppression on the add() method of Ext.util.History, I decided to implement a &#8220;fix&#8221; via Ext.apply(). Here&#8217;s the final result:</p>
<pre>Ext.apply(Ext.util.History,{
    <strong>suppressChange : false,</strong>
    add: function(token,preventDup,suppressChange) {
        var me = this;
        <strong>this.suppressChange = suppressChange ? true : false;</strong>
        if (preventDup !== false) {
            if (me.getToken() === token) {
                return true;
            }
        }
        if (me.oldIEMode) {
            return me.updateIFrame(token);
        } else {
            window.top.location.hash = token;
            return true;
        }
    },
    handleStateChange: function(token) {
        this.currentToken = token;
        <strong>// only fire "change" event if suppressChange is false</strong>
        <strong>if (!this.suppressChange) { this.fireEvent('change', token); }</strong>
        <strong>// now just reset the suppressChange flag</strong>
        <strong>this.suppressChange = false;</strong>
    }
});</pre>
<p>There are really 3 parts that are important.</p>
<p>The first is that I added another property to Ext.util.History, namely &#8220;suppressChange.&#8221; This flag will tell History whether or not to fire the change event.</p>
<p>The second is that I added another argument to the add() method, again, &#8220;suppressChange&#8221;. It will simply set the value of the Ext.util.History.suppressChange property.</p>
<p>Finally, in handleStateChange(), I wrapped the change event firing in a condition: if Ext.util.History.suppressChange is false, the change event will be fired; otherwise, it will not. And to wrap it up, the handleStateChange() method automatically resets the default value of the suppressChange property back to false so I don&#8217;t have to bother with that elsewhere, and since not suppressing the change event is the desired default behavior.</p>
<p>What this boils down to, then is that you don&#8217;t have to muck with your change event listener at all. Rather, you can simply add the suppressChange flag when executing the Ext.util.History.add() method, and let the rest flow on as normal:</p>
<pre>// add() invocation with suppressChange flag set to true
Ext.History.add(newtoken,true,<strong>true</strong>); //token, preventDuplicates, suppressChange</pre>
<h2>Wrapping Up</h2>
<p>And that&#8217;s that. To be perfectly honest, I&#8217;m not sure if this is *best* way to go about this, but in my testing it does work, at least for my purposes. I&#8217;d love to hear *constructive* feedback, suggestions on how to do it better, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/08/extjs-4-a-modified-ext-util-history/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

