<?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; JavaScript</title>
	<atom:link href="http://existdissolve.com/category/javascript/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>Sugar: A Bit of JavaScript Sweetness</title>
		<link>http://existdissolve.com/2012/01/sugar-a-bit-of-javascript-sweetness/</link>
		<comments>http://existdissolve.com/2012/01/sugar-a-bit-of-javascript-sweetness/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 03:11:34 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Sugar]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2306</guid>
		<description><![CDATA[Twitter never lets me down Today, I stumbled upon Sugar,  a really nice&#8211;and small&#8211;JavaScript library. Unlike monster libraries such as jQuery and ExtJS (which are awesome in their own ways&#8230;), Sugar is narrowly focused. It&#8217;s niche is simply extending native JS objects with intuitive methods. So want to capitalize the first word in a string?&#8230;]]></description>
			<content:encoded><![CDATA[<p>Twitter never lets me down <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Today, I stumbled upon <strong><a href="http://sugarjs.com/">Sugar,</a></strong>  a really nice&#8211;and small&#8211;JavaScript library. Unlike monster libraries such as jQuery and ExtJS (which are awesome in their own ways&#8230;), Sugar is narrowly focused. It&#8217;s niche is simply extending native JS objects with intuitive methods.</p>
<p>So want to capitalize the first word in a string? Easy: <strong>string.capitalize().</strong> Want to replace dashes/underscores with spaces? Nothing to it: <strong>string.spacify()</strong>.</p>
<p>I&#8217;ve worked up a quick couple of <a href="http://existdissolve.com/demos/sugar/">demos of a few of the string methods</a>, just to show how dead simple Sugar is to use. Of course, you should check out <a href="http://sugarjs.com/api">Sugar&#8217;s API</a> for the full enchilada. Mmmm, <a href="http://myfoodrecipes.net/wp-content/uploads/2010/03/enchiladas.jpg">enchildas</a>&#8230;</p>
<h2>Impressions</h2>
<p>While I am a die-hard <a href="http://www.sencha.com/products/extjs/">ExtJS</a> user, there is something about the simplicity of Sugar that I really like. While it certainly won&#8217;t give you the tools to build a full-fledged web app with components, data grids, and what-not, it&#8217;s perfect for the small or one-off websites/pages where JS&#8217; native objects could use some extra lovin&#8217;.</p>
<p>The one drawback (and it&#8217;s a slight one) is that there does not appear to be a way to do a custom build of Sugar to include *only* those methods which you need. <a href="http://blog.sugarjs.com/post/14400784842/sugar-dates-only-build">According to their blog</a>, this is because of some internals of Sugar that are needed throughout the library for IE support. What, IE ruining yet another otherwise great project? Surely not!</p>
<p>Although the custom-build-ness is lacking, the full library is only <strong>17k</strong> gzipped, so there&#8217;s really not a huge hit including the whole thing anyway. That&#8217;s what caching is for anyway, right?</p>
<h2>Wrapping Up</h2>
<p>Honestly, I haven&#8217;t looked closely at Sugar&#8217;s internals to make a judgement about how &#8220;well done&#8221; their extension of native JS objects is. However, my initial impression is that I really like the approach they&#8217;ve taken. The ridiculously simple implementation of their API makes Sugar a library worth keeping in mind when you&#8217;ve got some light to moderate JS-in&#8217; to do.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2012/01/sugar-a-bit-of-javascript-sweetness/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Resolutions and Stuff</title>
		<link>http://existdissolve.com/2012/01/resolutions-and-stuff/</link>
		<comments>http://existdissolve.com/2012/01/resolutions-and-stuff/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 14:26:21 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[2012]]></category>
		<category><![CDATA[Resolutions]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2300</guid>
		<description><![CDATA[I&#8217;m not big on resolutions. When I&#8217;ve made them in the past, I typically last about 3 whole days before they&#8217;re broken and forgotten. Besides, there&#8217;s something a bit odd about resolutions anyway. After all, why would we wait until a New Year to do something (lose weight, exercise more, etc.), when it makes a&#8230;]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not big on resolutions. When I&#8217;ve made them in the past, I typically last about 3 whole days before they&#8217;re broken and forgotten. Besides, there&#8217;s something a bit odd about resolutions anyway. After all, why would we wait until a New Year to do something (lose weight, exercise more, etc.), when it makes a lot more sense to do these things *before* the year begins so that we have the benefit of whatever change for the whole year?</p>
<p>Ah, but that&#8217;s the neurosis of the Western mind; what can be done about it? Nothing <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>But even though I&#8217;m reticent about making resolutions, I have been thinking about the year that lies ahead, particularly from a professional standpoint. Over the last year, I&#8217;ve been very productive in my professional development. Particularly in relation to ColdFusion, JavaScript and SQL, I have tremendously expanded my competency, and I feel quite comfortable with where I am as a developer.</p>
<p>However, as we all know, complacency can be a silent killer. While it may not immediately harm a person in relation to their employment prospects, it can be detrimental in the long-term, if nothing else than by souring them to the prospects of learning new skills, exploring new technologies, etc.</p>
<p>I don&#8217;t want this to ever happen. I don&#8217;t feel like it&#8217;s a particular danger right now; I&#8217;m a naturally inquisitive person, so exploring new technologies, improving skills, etc. is just something I like to do. However, I do see this problem manifest in others, and I don&#8217;t like what it looks like. So, in my pre-emptive attempts to ward off such a fate, I&#8217;ve come up with a resolution (or two) of sorts for 2012.</p>
<h2>Becoming &#8220;Expert&#8221;</h2>
<p>When it comes to ColdFusion and JavaScript development, I feel very confident in my abilities. For any task, no matter the complexity, I am more than capable of crafting a solution that utilizes these technologies. I don&#8217;t say that in arrogance; it&#8217;s simply a fact. Ater so many years of using each, I can accomplish many things&#8230;and very quickly at that.</p>
<p>But while I am fully capable of using these technologies, I am also keenly aware of the extent (and limitations) of my competency. I have no delusions about my understanding of CF and JS. Yes, I can <strong><em>use</em></strong> them quite capably to do just about anything that is proposed. However, in regard to a more fundamental knowledge about the technology <em>qua</em> technology, I find many gaps in my understanding.</p>
<p>Therefore, one of the things that I want to pursue in 2012 is to begin a journey of becoming &#8220;expert&#8221; in ColdFusion and JavaScript. To me, the &#8220;expert&#8221; part that I&#8217;m missing is precisely this deeper understanding of how each technology *works* apart from the day-to-day grind of *using* them to accomplish discreet tasks. So this will mean that I will probably be doing a lot more reading about the technologies than actually using them. And you know what? I think that&#8217;s okay. The school of &#8220;learning by doing&#8221; has gotten me a VERY long way in my career. However, I think the next step wil come only by a very deep commitment to learning the bits that won&#8217;t necessarily come by trial and error.</p>
<p>You&#8217;ll notice I said &#8220;begin a journey.&#8221; I don&#8217;t expect to become &#8220;expert&#8221; by the end of 2012. However, I do want to determine a path that will get me where I intend to go. If I can accomplish just that, 2012 will have been a success.</p>
<h2>Explore New Frontiers</h2>
<p>One of the biggest keys to professional development, especially when it comes to web development, is to have an expansive portfolio of skills. This doesn&#8217;t mean, of course, that one needs to be &#8220;expert&#8221; in 7 different languages; that would probably be impossible for most people. However, it does mean that one is open to actively pursuing an understanding of how different technologies work and how each can be leveraged in various situations to accomplish particular goals.</p>
<p>In the coming year, there are a lot of technologies that I want to explore. In order to not get completely overwhelmed, I&#8217;m going to take a dual approach.</p>
<p>First, I&#8217;ve selected a handful that I want to do more of a &#8220;deep dive&#8221; into; these will require several weeks/months of exploration each. By the end of the year, I&#8217;d like to be able to say that I have a base-level competency with each technology&#8211;not something on the basis of which you&#8217;d hire me, but a working knowledge expansive enough to be able to accomplish <em>something</em>, and a solid foundation upon which I can build in the future. Here are the targets:</p>
<ul>
<li>Ruby</li>
<li>Node.js</li>
<li>jQuery</li>
<li>Python</li>
<li>ORM</li>
<li>Git</li>
</ul>
<p>Second, I want to build time into each week to take an hour or two to make a surface exploration of new technologies/snippets/etc. that I come across in the course of my daily blog trolling. So for example, if a new JavaScript framework is highlighted in one of the blogs I read, I want to explore that. My intention is, at the very most, to devote enough time to make a surface exploration. While this will not by any means make me competent in this or that technology, I think the practice will help to expand my skill set, simply by seeing how other people do things. I don&#8217;t have a discreet list for these, as I hope to leave time open for exploration as opportunities present themselves.</p>
<h2>Avoiding Blackhole Projects</h2>
<p>Over the last year, I found myself buried in blackhole projects. These were projects that I came up with on my own that didn&#8217;t have particular goals, or defined execution plans. With each of them, I started with the *intention* of learning/doing something new. However, I dreamed way too big, never accomplished whatever I had set out to do, and wasted a ton of time and effort for nothing except frustration.</p>
<p>In 2012, I&#8217;m going to make a concerted effort to avoid projects altogether. I&#8217;ve found that projects tend to devour an inordinate amount of time, simply because I end up spending a lot of effort on things that aren&#8217;t even central to the project itself (like getting the design pixel perfect, abstracting the 20 lines of JavaScript being used, etc.). So instead of using projects as a way of exploring this or that technology, I&#8217;m going to try to focus on simply executing very small, manageable development tasks. Whether this is simply creating a nice &#8220;Hello world&#8221; or developing some extension/module/whatever, keeping the scope tiny and defined will hopefully help me be much more productive in my learning and exploration.</p>
<h2>Blogging</h2>
<p>My blogging output in 2011 was a little underwhelming. While I did add some fairly in-depth posts, the number of posts was a bit disappointing. While quantity doesn&#8217;t really mean anything, it does reiterate to me the project blackhole problem I had during the year. So one of the things I really want to focus on in 2012 is becoming a better blogger. For me, I think this means being more intentional about regularly positing my experiences, while also not being quite so concerned with feeling like I have to write a novel each time.</p>
<h2>Wrapping Up</h2>
<p>So, it&#8217;s an ambitious plan for 2012. However, I&#8217;ve already made one important step: today, I officially abandoned a blackhole project that I had started last week. I&#8217;m beginning with a clean slate, and am looking forward to a great year of leaning, improving, and expansion of my development skills.</p>
<p>If anyone has any constructive thoughts/suggestions, I&#8217;d love to hear them!</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2012/01/resolutions-and-stuff/feed/</wfw:commentRss>
		<slash:comments>0</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>Sencha Touch Theming: Custom UIs</title>
		<link>http://existdissolve.com/2011/09/sencha-touch-theming-custom-uis/</link>
		<comments>http://existdissolve.com/2011/09/sencha-touch-theming-custom-uis/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 22:24:27 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[Sencha Touch]]></category>
		<category><![CDATA[theming]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2236</guid>
		<description><![CDATA[During the course of developing your Sencha Touch app, you will inevitably get around to theming&#8230;after all, while the default styles are nice, they don&#8217;t exactly scream individuality. Fortunately, Sencha Touch makes theming ridiculously easy, and there are a lot of resources available to help with getting started with that. But let&#8217;s talk about a&#8230;]]></description>
			<content:encoded><![CDATA[<p>During the course of developing your Sencha Touch app, you will inevitably get around to theming&#8230;after all, while the default styles are nice, they don&#8217;t exactly scream individuality. Fortunately, Sencha Touch makes theming ridiculously easy, and there are a lot of resources available to help with getting started with that.</p>
<p>But let&#8217;s talk about a specific example. Let&#8217;s imagine that you want to simply change the background color on your app&#8217;s toolbars. The first thing you&#8217;ll probably do is pop open Firebug or Developer Tools to inspect the CSS that&#8217;s being applied to your toolbar. Unless you&#8217;ve already customized it, you&#8217;ll probably seem something like this:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.46.49-PM.png"><img class="size-full wp-image-2241 alignnone" style="display: block;" title="Screen Shot 2011-09-26 at 9.46.49 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.46.49-PM.png" alt="" width="581" height="161" /></a></p>
<p>I&#8217;ve highlighted &#8220;x-toolbar-dark&#8221;, because by default, the &#8220;UI&#8221; configuration option for Ext.Toolbar is set to &#8220;dark,&#8221; which applies the &#8220;x-toolbar-dark&#8221; class to your toolbar (it will apply &#8220;x-toolbar-light&#8221; if you specify &#8220;light&#8221; for ui&#8230;more on this later).</p>
<p>Here&#8217;s what the toolbar actually looks like:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.46.27-PM.png"><img class="size-full wp-image-2242 alignnone" style="display: block;" title="Screen Shot 2011-09-26 at 9.46.27 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.46.27-PM.png" alt="" width="322" height="51" /></a></p>
<p>If you inspect the properties of this CSS class, you should see something like this:</p>
<ul>
<li title="background-color:#456f8d;">background-color: #456F8D;</li>
<li title="background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #9cbacf), color-stop(2%, #5182a5), color-stop(100%, #395c75));">background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #9cbacf), color-stop(2%, #5182a5), color-stop(100%, #395c75));</li>
<li title="background-image:-webkit-linear-gradient(#9cbacf,#5182a5 2%,#395c75);">background-image: -webkit-linear-gradient(#9cbacf,#5182a5 2%,#395c75);</li>
<li title="background-image:linear-gradient(#9cbacf,#5182a5 2%,#395c75);">background-image: linear-gradient(#9cbacf,#5182a5 2%,#395c75);</li>
<li title="border-color:#000">border-color: black;</li>
</ul>
<p>Nothing too crazy here&#8230;just some background-image gradients to give the toolbar a nice textured feel. Now at this point, you might be tempted to do something crazy, something like creating a new class in an <strong><em>extra</em></strong> custom stylesheet to override these style rules. Or, you might add a custom class via the Ext.Toolbar&#8217;s &#8220;cls&#8221; config, and add the styles for this custom class in your custom stylesheet.</p>
<p>While both of these options will certainly work, they miss out on the power of theming within Sencha Touch. So let&#8217;s look at a better way to approach this.</p>
<h2>Toolbar UI</h2>
<p>If you look at the <a href="http://dev.sencha.com/deploy/touch/docs/?class=Ext.Toolbar">documentation for Ext.Toolbar </a>(as well as several of the other common components), you&#8217;ll notice that it has a config option for &#8220;ui&#8221;. By default, you can specify either &#8220;dark&#8221; or &#8220;light,&#8221; which is what applies either the &#8220;x-toolbar-dark&#8221; or &#8220;x-toolbar-light&#8221; classes to our toolbar. So knowing this, the ideal approach to customizing our toolbar&#8217;s style is not by creating custom, external style rules to override or circumvent default Sencha Touch styling, but rather to create our own &#8220;ui&#8221; that we can use in the configuration of our Ext.Toolbar itself.</p>
<p>Fortunately, this is ridiculously easy&#8230;but first, some context <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Default Toolbar UIs</h2>
<p>As mentioned, the Toolbar has two default UIs: dark and light. By specifying either of these in the configuration of your Ext.Toolbar, you can easily switch between the two to get the feel that you would like (this is especially helpful if you have stacked toolbars).  Let&#8217;s take a look at how these UIs are created.</p>
<p>First, we&#8217;ll need to find the .scss (Sassy CSS) file that generates the toolbar CSS classes. You can find that here:</p>
<p><strong>sencha-touch-1.1.0/resources/themes/stylesheets/sencha-touch/default/widgets/_toolbar.scss</strong></p>
<p>A ways down the page, you&#8217;ll see something like the following:</p>
<pre>@include sencha-toolbar-ui('dark', darken($base-color, 10%));
@include sencha-toolbar-ui('light', $base-color);</pre>
<p>Here, our two default UIs are created. This is done by using the <strong>sencha-toolbar-ui</strong> <a href="http://sass-lang.com/#mixins">&#8220;mixin,&#8221;</a> which is really just a mechanism to allow you reuse chunks of code to construct CSS classes. The great part about mixins, though, is that you can utilize arguments, so it makes creating custom iterations of the same family of classes super easy.</p>
<p>Now let&#8217;s take a look at the mixin itself:</p>
<pre>@mixin sencha-toolbar-ui($ui-label, $color, $gradient: $toolbar-gradient) {
   $toolbar-border-color: darken($color, 50%);
   $toolbar-button-color: darken($color, 10%);
   .x-toolbar-#{$ui-label} {
      @include background-gradient($color, $gradient);
      border-color: $toolbar-border-color;
      .x-toolbar-title {
         @include color-by-background($color);
         @include bevel-by-background($color);
      }
      .x-button, .x-field-select .x-input-text, .x-field-select:before {
         @include toolbar-button($toolbar-button-color, $gradient);
      }
   }
}</pre>
<p>As you can see, the mixing takes up to 3 arguments:</p>
<ul>
<li>The name of the UI</li>
<li>The base color for the UI</li>
<li>The type of gradient to use for the UI (defaults to the variable $toolbar-gradient)</li>
</ul>
<p>Then, based on the arguments passed, this mixin will create a CSS class in the form of &#8220;x-toolbar-[UI Name]&#8220;, and will additionally create classes that riff on the color and gradient that are specified for the overall UI. This will give the toolbar a unified &#8220;feel&#8221; if it contains buttons.</p>
<h2>Creating our Own Toolbar UI</h2>
<p>While this UI/SASS/mixin stuff can be a little overwhelming at first, hopefully you see now how it starts to come together. Since we know that the &#8220;dark&#8221; and &#8220;light&#8221; UIs for the toolbar are crafted simply by using the sencha-toolbar-ui mixin, it&#8217;s pretty clear how we need to proceed to create our own UI. So let&#8217;s do that now.</p>
<p>In <strong>sencha-touch-1.1.0/resources/sass/</strong>, I&#8217;ve created a custom .scss file (I&#8217;ve called it &#8220;custom&#8221;&#8230;pretty original, I know). In this .scss file, I&#8217;m going to create a custom toolbar UI. Since &#8220;blue&#8221; is way to predictable for a developer, I want to try something sheik, but safe. How about a nice &#8220;charcoal&#8221; UI?</p>
<p>Here&#8217;s how we do it:</p>
<div>
<pre>$base-color: #588aad; // go big blue!
$include_default_icons: false;
@import 'sencha-touch/default/all';
@include sencha-panel;
@include sencha-buttons;
@include sencha-sheet;
@include sencha-picker;
@include sencha-tabs;
@include sencha-toolbar;
@include sencha-toolbar-forms;
@include sencha-indexbar;
@include sencha-list;
@include sencha-layout;
@include sencha-form;
@include sencha-msgbox;
@include sencha-loading-spinner;

@include pictos-iconmask("bookmarks");
@include pictos-iconmask("compose");
@include pictos-iconmask("trash");
@include pictos-iconmask("search");
@include pictos-iconmask("my-logo");
@include pictos-iconmask("bookmark2");

<strong>@include sencha-toolbar-ui('charcoal', #333333,'glossy');</strong></pre>
</div>
<p>Ok, 98% of the code above has nothing to do with our custom UI. I just wanted to include it, in case you&#8217;ve never seen an .scss file. The most important line for our UI is the last one.</p>
<p>What? One line? Is that really all there is to creating a custom toolbar UI? The simple answer is <strong>YES</strong>.</p>
<p>Easy, right? And this is precisely why I advocate for creating the custom UI, over and against modification of a custom stylesheet. With the custom UI, we don&#8217;t need to do anything else besides this one line of code here. Any maintenance moving forward (like tweaking for a more nuanced &#8220;charcoal&#8221; color) will only require a quick modification here. No extra style sheet to worry about, which is always a good thing.</p>
<h2>Using the Custom UI</h2>
<p>Alright, so we&#8217;ve created our custom UI. How do we use it?</p>
<p>Well, first, we&#8217;re going to need to recompile our app&#8217;s stylesheet.</p>
<p>In Terminal, navigate to <strong>sencha-touch-1.1.0/resources/sass</strong> (where we created our custom .scss file), and then type &#8220;<strong>compass compile</strong>&#8220;. If everything goes through ok, you should now see a &#8220;custom.css&#8221; (or whatever you named it) in the <strong>sencha-touch-1.1.0/resources/css</strong> folder.</p>
<blockquote><p>If you have <strong><em>no idea</em></strong> what&#8217;s going on here, take a look at this article on <a title="Sencha Touch Theming: Getting Started" href="http://existdissolve.com/2011/03/sencha-touch-theming-getting-started/">getting setup for theming in Sencha Touch</a>.</p></blockquote>
<p>Take this path to your custom CSS file and add it to your main application file so that it&#8217;s using it as the main CSS.</p>
<p>Good? Ok, now we can apply our custom UI to a toolbar!</p>
<pre>var myToolbar = new Ext.Toolbar({
   dock: "top",
   title: "Fancy Charcoal Toolbar in the House!",
  <strong> ui: "charcoal"</strong>
});</pre>
<p>That&#8217;s it! Save your work, refresh your browser, and you should now see your app with a sheik, sophisticated charcoal toolbar <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The final result?</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.50.32-PM.png"><img title="Screen Shot 2011-09-26 at 9.50.32 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.50.32-PM.png" alt="" width="323" height="49" /></a></p>
<p>And the underlying HTML:</p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.50.12-PM.png"><img title="Screen Shot 2011-09-26 at 9.50.12 PM" src="http://existdissolve.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-9.50.12-PM.png" alt="" width="587" height="158" /></a></p>
<p>(Notice it&#8217;s exactly the same as before, but now with the new UI class of &#8220;charcoal&#8221;)</p>
<h2>Wrapping Up</h2>
<p>I can&#8217;t understate the point enough that what&#8217;s been outlined above has only scratched the surface of what&#8217;s possible. But hopefully it demonstrates some of the really cool things that can be accomplished with very little effort, and in such a way that is a natural extension of Sencha Touch&#8217;s powerful theming capabilities.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/09/sencha-touch-theming-custom-uis/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

