Friends and life

I’m a very open and honest person; I don’t try to be something I’m not. I will always admit I don’t know everything which is actually one of the values of myself that I hold dear, it helps me always push myself.

Some of you may have noticed that I got engaged recently and am trying to plan a wedding which looks to be end of April 2013 so Danielle and I have plenty of time to plan. First up is location and picking guest list and the wedding party. All this planning is both fun and overwhelming, I knew there would be a lot of things but dealing with a woman who has been thinking about ideas for last 25 or so years quite a lot to keep up with.

Back when I was a teenager I was a very sensitive person which I allowed for things to hurt me. So as I matured I tried to grow away from that and have successfully been able to control my emotions a lot more. Hell, controlling what I think about has become pretty easy minus the big life things. So as I am planning the wedding and picking my wedding party I realized something that, to be honest, bothers me… friends.

When I was young, talking before I was 16, I had friends that I would hang out with. Once I started working I lost those friends and gained new ones which is fine. I’ve gone through a couple evolutions in my life and in each evolution I lost all my friends as they weren’t able or willing to be ok with my changes. They were friends but not good friends. There is one friend that has stuck with me for last 10 years and no doubt will be (and has accepted) to be my best man but I can’t have a wedding party of one. In my current evolution, my “geek” evolution I have made many new friends and am very happy with where I am with these friends but it still bothers me that I don’t have more friends from back when I was a kid or a teenager. I have pretty much chosen who is in my wedding party (haven’t asked everyone yet) and couldn’t be more thrilled for the group of guys I will be having don’t get me wrong, I have been in a couple wedding recently and see them having friends that have been around for a long time.

I guess the moral of this is growing up sucks. You want to hold on to what was but still move towards what will be. It’s a struggle, it’s a personal struggle. I have told Danielle that you can’t live in the past, all you can do is learn and move on. But your past is what made you, what sculpted you.

Disclaimer – I know this is personal and not really tech related but it is therapeutic to write things.

JSONPLint.com is Here!

Hopefully you have used both JSLint.com or JSONLint.com to validate and maybe just for some formatting of your code. If you haven’t, shame!

I work at Sencha providing crazy fast support on the forums and a lot of times I need to look at the response people are using. Either it’s JSON, JSONP or on a bad day it’s XML. I use JSONLint.com to make the JSON or JSONP readable and also tell me if it’s even valid. JSONLint.com does a fantastic job for me but when I have JSONP I have to manually remove the callback function to only have the JSON or else JSONLint.com will yell at me.

So I decided to do something about it and registered JSONPLint.com just so I can make sure the actual JSON is valid and also see if the JSONP is actually valid. I found out Zach Carter actually does the pure JavaScript JSON validation behind JSONLint.com and has the code up on GitHub (here) which is fantastic and makes my life easier. All I have to do is remove the callback function and validate the actual JSON which is easy. So I modified Zach Carter’s example to do just that and did some coloring to fit my own needs for a first draft.

What’s next? First, need to clean it up. Got the first draft done but there is a better way to strip out the callback function. After that I would like to support url calling where you can pass params and headers so you can lint remote JSONP right from JSONPLint.com

Fullscreen Madness!

Sencha Touch 2 is a fantastic framework, my favorite to work with and most likely will be until Sencha Touch 3 comes out (no public dates yet :) ). I’m a mobile developer at heart I guess or maybe I just like that I don’t have to worry about IE. Either case Sencha Touch 2 is fantastic and by looking at the popularity in the Sencha Touch 2 forums I’m not the only one loving it! Helping people out a lot, I’m noticing a lot of people using the fullscreen config option where they shouldn’t which makes me think that the function of the fullscreen config isn’t explained very well. Today, I hope to change this.

Ext.Viewport

Before we dive into what the fullscreen config does, I want to make you aware of a critical piece of the puzzle. When you launch a Sencha Touch 2 app, the framework creates a component that will act as the viewport for your app. The instance is saved to Ext.Viewport. Quick explanation of what Ext.Viewport is is it’s an Ext.Container using card layout. Bit more info is you may have noticed the classes in the Ext.viewport namespace (remember JavaScript is case-sensitive so Ext.Viewport !== Ext.viewport). Ext.viewport.Android and Ext.viewport.Ios both extend Ext.viewport.Default and help setup the viewport based on what platform is currently viewing your application. Ext.viewport.Viewport acts as a factory for creating the correct viewport class. Each platform has it’s own quirks and issues and this helps navigate around these to provide better performance.

You can configure the Ext.Viewport by using the viewport config in Ext.setup or the viewport config in Ext.application. Each link links to the online API Docs and there are examples for this so I don’t have to show that code.

To sum Ext.Viewport up… Ext.Viewport is an Ext.Container and by default it uses card layout.

fullscreen Config!

First, let’s look at a small code snippet and then break it down:

new Ext.Container({
    fullscreen : true,
    html       : 'Do you seem my size?',
    items      : [
        {
            xtype  : 'toolbar',
            docked : 'top',
            title  : 'Top Toolbar'
        },
        {
            xtype  : 'toolbar',
            docked : 'bottom',
            title  : 'Bottom Toolbar'
        }
    ]
});

I added the two toolbars so you can visually see the size of the Ext.Container we created. The important part we need to talk about is that fullscreen config. So you noticed that the Ext.Container took 100% of the height and width but how did it do that? Remember Ext.Viewport? When you create a component (using the new keyword like I did or Ext.create) with the fullscreen config set to true (defaults to false) it actually fires a fullscreen event on itself. Within Ext.viewport.Default, it has a listener for fullscreen events and when it captures one, it will take that component and add it as an item of Ext.Viewport. Since by default Ext.Viewport uses card layout the Ext.Container that was just added as an item will take up 100% of the height and width because that’s what card layout does.

To recap this, Ext.Viewport listens for fullscreen events and adds that Ext.Component as an item.

Multiple fullscreens

What happens when we have two or more components using fullscreen set to true? Well, it keeps adding those components and adds them as a child item but you will only be able to see one at a time as that is how card layout works. You can use the setActiveItem method on Ext.Viewport to navigate through your “fullscreen” components:

new Ext.Container({
    fullscreen : true,
    html       : 'Do you seem my size?',
    items      : [
        {
            xtype  : 'toolbar',
            docked : 'top',
            title  : 'Top Toolbar',
            items  : [
                {
                    text    : 'Go 2nd',
                    ui      : 'confirm',
                    handler : function() {
                        Ext.Viewport.setActiveItem(1);
                    }
                }
            ]
        },
        {
            xtype  : 'toolbar',
            docked : 'bottom',
            title  : 'Bottom Toolbar'
        }
    ]
});

new Ext.Container({
    fullscreen : true,
    html       : 'Second One'
});

So we have two Ext.Containers using fullscreen set to true. The active item will be the first container as Ext.Viewport won’t change the active item, it will just add it as an item. I added a button to the top toolbar of the first container that simple executes Ext.Viewport.setActiveItem(1) which will switch to the item at index 1 of Ext.Viewport which is the second container.

Summary

We quickly learned what Ext.Viewport is and how to configure it. We then dove into how the fullscreen config works behind the scenes and then saw how we can use multiple items with the fullscreen config set to true.

ActionColumn and MVC

Being full-time on the Sencha forums gives me direct access to the community which gives me an idea of some frequently asked questions that I hope to blog more to answer.

Mission

Building applications with Ext JS 4 is very easy with the MVC architecture but sometimes it’s not always easy to know how to use MVC with certain widgets or features of Ext JS 4. Today I would like to discuss how I went about using ActionColumns and MVC specifically how to control when you click on an ActionColumn item within a controller.

Setting the Stage

Let’s set the stage! I’m going to use the Array Grid example that comes with every Ext JS release but turn it from an ordinary example into a more MVC example. Here are the controller, model, view and application code that we can start with:

Ext.define('Mitch.controller.Main', {
    extend : 'Ext.app.Controller',

    init : function() {
        //this.control will go here
    }
});

Ext.define('Mitch.model.Company', {
    extend : 'Ext.data.Model',

    idProperty : 'company',
    fields     : [
       { name : 'company'                                            },
       { name : 'price',      type : 'float'                         },
       { name : 'change',     type : 'float'                         },
       { name : 'pctChange',  type : 'float'                         },
       { name : 'lastChange', type : 'date', dateFormat : 'n/j h:ia' }
    ]
});

Ext.define('Mitch.view.Viewport', {
    extend : 'Ext.grid.Panel',
    xtype  : 'mitch-viewport',

    multiSelect : true,
    height      : 350,
    width       : 600,
    title       : 'Array Grid',

    initComponent : function() {
        var me = this;

        me.columns    = me.buildColumns();
        me.store      = me.buildStore();
        me.viewConfig = {
            stripeRows          : true,
            enableTextSelection : true
        };

        Mitch.view.Viewport.superclass.initComponent.call(me);
    },

    buildStore : function() {
        return new Ext.data.Store({
            model : 'Mitch.model.Company',
            data  : [
                ['3m Co',                               71.72, 0.02,  0.03,  '9/1 12:00am'],
                ['Alcoa Inc',                           29.01, 0.42,  1.47,  '9/1 12:00am'],
                ['Altria Group Inc',                    83.81, 0.28,  0.34,  '9/1 12:00am'],
                ['American Express Company',            52.55, 0.01,  0.02,  '9/1 12:00am'],
                ['American International Group, Inc.',  64.13, 0.31,  0.49,  '9/1 12:00am'],
                ['AT&T Inc.',                           31.61, -0.48, -1.54, '9/1 12:00am'],
                ['Boeing Co.',                          75.43, 0.53,  0.71,  '9/1 12:00am'],
                ['Caterpillar Inc.',                    67.27, 0.92,  1.39,  '9/1 12:00am'],
                ['Citigroup, Inc.',                     49.37, 0.02,  0.04,  '9/1 12:00am'],
                ['E.I. du Pont de Nemours and Company', 40.48, 0.51,  1.28,  '9/1 12:00am'],
                ['Exxon Mobil Corp',                    68.1,  -0.43, -0.64, '9/1 12:00am'],
                ['General Electric Company',            34.14, -0.08, -0.23, '9/1 12:00am'],
                ['General Motors Corporation',          30.27, 1.09,  3.74,  '9/1 12:00am'],
                ['Hewlett-Packard Co.',                 36.53, -0.03, -0.08, '9/1 12:00am'],
                ['Honeywell Intl Inc',                  38.77, 0.05,  0.13,  '9/1 12:00am'],
                ['Intel Corporation',                   19.88, 0.31,  1.58,  '9/1 12:00am'],
                ['International Business Machines',     81.41, 0.44,  0.54,  '9/1 12:00am'],
                ['Johnson & Johnson',                   64.72, 0.06,  0.09,  '9/1 12:00am'],
                ['JP Morgan & Chase & Co',              45.73, 0.07,  0.15,  '9/1 12:00am'],
                ['McDonald\'s Corporation',             36.76, 0.86,  2.40,  '9/1 12:00am'],
                ['Merck & Co., Inc.',                   40.96, 0.41,  1.01,  '9/1 12:00am'],
                ['Microsoft Corporation',               25.84, 0.14,  0.54,  '9/1 12:00am'],
                ['Pfizer Inc',                          27.96, 0.4,   1.45,  '9/1 12:00am'],
                ['The Coca-Cola Company',               45.07, 0.26,  0.58,  '9/1 12:00am'],
                ['The Home Depot, Inc.',                34.64, 0.35,  1.02,  '9/1 12:00am'],
                ['The Procter & Gamble Company',        61.91, 0.01,  0.02,  '9/1 12:00am'],
                ['United Technologies Corporation',     63.26, 0.55,  0.88,  '9/1 12:00am'],
                ['Verizon Communications',              35.57, 0.39,  1.11,  '9/1 12:00am'],
                ['Wal-Mart Stores, Inc.',               45.45, 0.73,  1.63,  '9/1 12:00am']
            ]
        });
    },

    buildColumns : function() {
        return [
            {
                text      : 'Company',
                flex      : 1,
                sortable  : false,
                dataIndex : 'company'
            },
            {
                text      : 'Price',
                width     : 75,
                sortable  : true,
                renderer  : 'usMoney',
                dataIndex : 'price'
            },
            {
                text      : 'Change',
                width     : 75,
                sortable  : true,
                renderer  : 'usMoney',
                dataIndex : 'change'
            },
            {
                text      : '% Change',
                width     : 75,
                sortable  : true,
                renderer  : function(v) { return v + '%'; },
                dataIndex : 'pctChange'
            },
            {
                text      : 'Last Updated',
                width     : 85,
                sortable  : true,
                renderer  : Ext.util.Format.dateRenderer('m/d/Y'),
                dataIndex : 'lastChange'
            },
            {
                xtype        : 'actioncolumn',
                menuDisabled : true,
                sortable     : false,
                width        : 50,
                items        : [
                    {
                        icon    : '../SDK/extjs/examples/shared/icons/fam/delete.gif',
                        tooltip : 'Sell stock',
                        handler : function(grid, rowIndex, colIndex) {
                            var rec = store.getAt(rowIndex);
                            alert("Sell " + rec.get('company'));
                        }
                    },
                    {
                        getClass : function(v, meta, rec) {
                            if (rec.get('change') < 0) {
                                this.items[1].tooltip = 'Hold stock';
                                return 'alert-col';
                            } else {
                                this.items[1].tooltip = 'Buy stock';
                                return 'buy-col';
                            }
                        },
                        handler  : function(grid, rowIndex, colIndex) {
                            var rec = grid.getStore().getAt(rowIndex);
                            alert((rec.get('change') < 0 ? "Hold " : "Buy ") + rec.get('company'));
                        }
                    }
                ]
            }
        ];
    }
});

Ext.application({
    name        : 'Mitch',
    controllers : [ 'Main' ],

    launch : function() {
        new Mitch.view.Viewport({
            renderTo : document.body
        });
    }
});

Bunch of code but very easy to follow. Currently the Main controller doesn’t do anything and you can see we have two items under the ActionColumn but it’s not very MVCish. I know you can use the ComponentQuery ‘mitch-viewport actioncolumn’ to resolve the ActionColumn so in the Main controller I just decided to test if I can listen to the a click event on the ActionColumn in a controller and it actually worked! Here is how to capture the click event:

Ext.define('Mitch.controller.Main', {
    extend : 'Ext.app.Controller',

    init : function() {
        this.control({
            'mitch-viewport actioncolumn' : {
                click : this.handleActionColumn
            }
        });
    },

    handleActionColumn : function(gridview, el, rowIndex, colIndex, e, rec, rowEl) {
        console.log(arguments);
    }
});

So if you click on an item in the ActionColumn the controller will console.log the arguments out so you can inspect them. You could actually stop here and use this as is but upon inspecting the different arguments (there are quite a few) I saw a problem… there isn’t an easy way to distinguish which icon in the ActionColumn was actually clicked on. You could add some logic in to look look at the actual target to see which icon was clicked on but there is an easier and less expensive way than parsing the DOM.

Custom Events

I would hope we all know that you don’t have to stick with the default events that are fired within the framework, we can actually fire custom events using fireEvent but I know I didn’t have that thought when I first started off. So why not use fireEvent within the handler of each item in the ActionColumn so that we don’t have to dig into the DOM? Why have a catch-all click event that is on the column? We can have a general event that is fired but easily distinguishable from one another and name it ‘itemclick’!

Fire itemclick

So we chose to fire a custom event call ‘itemclick’, first we need to decide what kind of arguments we want to fire this event with. The scope of the handler is that of the ActionColumn which is where we are going to fire the event on. We would maybe want the ActionColumn, grid, rowIndex, colIndex, record, eventObject, the node clicked on and since we are firing the event, we can make it easy on ourselves and put a custom argument to tell the action we should take. Let’s look at the code:

            {
                xtype        : 'actioncolumn',
                menuDisabled : true,
                sortable     : false,
                width        : 50,
                items        : [
                    {
                        icon    : '../SDK/extjs/examples/shared/icons/fam/delete.gif',
                        tooltip : 'Sell stock',
                        handler : function(grid, rowIndex, colIndex, node, e, record, rowNode) {
                            this.fireEvent('itemclick', this, 'sell', grid, rowIndex, colIndex, record, node);
                        }
                    },
                    {
                        getClass : function(v, meta, rec) { /* */ },
                        handler  : function(grid, rowIndex, colIndex, node, e, record, rowNode) {
                            var action = record.get('change') < 0 ? 'hold' : 'buy';
                            this.fireEvent('itemclick', this, action, grid, rowIndex, colIndex, record, node);
                        }
                    }
                ]
            }

So you can see how we can use the fireEvent and fired the ‘itemclick’ event onto this which is the ActionColumn. Now we can update the Main controller like this:

Ext.define('Mitch.controller.Main', {
    extend : 'Ext.app.Controller',

    init : function() {
        this.control({
            'mitch-viewport actioncolumn' : {
                itemclick : this.handleActionColumn
            }
        });
    },

    handleActionColumn : function(column, action, grid, rowIndex, colIndex, record, node) {
        console.log(action);
    }
});

If you update the view and the controller now and click on an icon in the ActionColumn, you would see the action console.log into the developer tools console being one of these options: ‘sell’, ‘hold’ or ‘buy’. Now based on that action we can then do whatever application and business logic that is required. Since we have the power of firing our own event you could actually fire the event on the grid itself so that your control method in your controller is easily managable and not have too many different ComponentQuery selectors but I would prefix the ‘itemclick’ event with ‘action’ so that the event name means something and doesn’t collide with any existing events.

Recap

First we took the Array Grid example and turned it into a simple MVC application. We then tested to see what events fire on the ActionColumn that we could use and found the click event was fired on the ActionColumn even though that particular event is documented in the API docs (I looked at the source for the ActionColumn and saw the possibility, don’t be afraid to look at the source!). We inspected the arguments that are fired with the click event and saw that we could use it but would have to query the DOM to see which item in the ActionColumn was actually clicked on. We decided that there could be a less expensive way to accomplish what we wanted to do than to play with the DOM as doing anything with the DOM (read/write) has a high performance hit. We found out we can fire our own events which should be faster than the DOM and so we modified our code to do this and found out it was very simple to do! Now we can go forth and do actual actions with our custom ‘itemclick’ event!

Ext.define and listeners as a property… bad!

Recently I have noticed a lot of people on the forums using the listeners, in my opinion, the wrong way. Being event driven is a great tactic in application development, one that I often use. Template methods are great and have their uses but for things that are reacting to user interactions, events are going to be your best friend.

Let’s look at a quick piece of code. Grids are used a lot and I often create an abstract class to handle all my grids as most of the stuff in grids can be abstracted out instead of having tons of duplicate code.

Ext.define('MyApp.view.grid.Abstract', {
    extend : 'Ext.grid.Panel',
    alias  : 'widget.myapp-grid-abstract',

    initComponent : function() {
        Ext.apply(this, {
            dockedItems : this.buildDocks(),
            selModel    : this.buildSelModel()
        });

        this.callParent(arguments);
    },

    buildDocks : function() {
        var docks = Ext.Array.from(this.dockedItems);

        docks.push({
            xtype : 'toolbar',
            dock  : 'top',
            items : [
                {
                    text     : 'Delete',
                    disabled : true,
                    action   : 'delete'
                }
            ]
        });

        return docks;
    },

    buildSelModel : function() {
        return {
            type : 'rowmodel',
            mode : 'SIMPLE'
        };
    }
});

So you can see from this code (which usually isn’t the entire abstract class) that we are adding a top docked Ext.Toolbar with a disabled delete button and defining a selection model with mode set to ‘SIMPLE’. The delete button should enable and disable based on the number of rows selected, disabled if the number of rows selected is zero, otherwise enable it. Usually you would extend an abstract class but for this blog we will just instantiate the abstract class like this:

new MyApp.view.grid.Abstract({
    renderTo : Ext.getBody(),
    width    : 400,
    height   : 400,
    title    : 'Test Grid',
    columns  : [
        {
            header    : 'Row',
            flex      : 1,
            dataIndex : 'row'
        }
    ],
    store    : new Ext.data.Store({
        fields : ['row'],
        data   : [
            { row : 'One'   },
            { row : 'Two'   },
            { row : 'Three' },
            { row : 'Four'  },
            { row : 'Five'  }
        ]
    })
});

So now we have a grid rendering as expected, time to handle the user interaction using the selectionchange event on the grid panel. This is where the problem lies. I have seen many developers add listeners like this:

Ext.define('MyApp.view.grid.Abstract', {
    extend : 'Ext.grid.Panel',
    alias  : 'widget.grid-abstract',

    listeners : {
        selectionchange : function(selModel, selected) {
            var view = selModel.view,
                grid = view.up('gridpanel'),
                btn  = grid.down('button[action=delete]');

            btn.setDisabled(selected.length === 0);
        }
    },

    initComponent : function() {
        /**/
    },

    buildDocks : function() {
        /**/
    },

    buildSelModel : function() {
        /**/
    }
});

Notice the listeners property we just set on the class’ prototype. And this works but I have always been told just because it works doesn’t mean it’s right; to me, this is an invalid use of listeners. listeners is listed as a config option so what happens when you instantiate the class like so:

new MyApp.view.grid.Abstract({
    /**/
    listeners : {
        afterrender : function() {
            console.log('my grid has rendered!');
        }
    }
});

Now, try to enable that delete button by selecting a row. Did it work? The problem here is anything you pass in the config object will overwrite anything you set on the prototype in Ext.define so the listeners you set to listen for the selectionchange event is now overwritten by the listeners config object listening for the afterrender when we instantiated. You now easily broke your abstract class. This is why you should never use listeners when using Ext.define.

So how do we go about to rectify this situation so that we can have our config listeners not overwrite our class listeners? The simple usage of on() will allow this, the only cavet is that we have to clean up the listener but that’s simple. Let’s delete the listeners from the Ext.define and put the on() usage into initComponent and use un() in beforeDestroy:

Ext.define('MyApp.view.grid.Abstract', {
    extend : 'Ext.grid.Panel',
    alias  : 'widget.grid-abstract',

    initComponent : function() {
        var me = this;

        Ext.apply(me, {
            dockedItems : me.buildDocks(),
            selModel    : me.buildSelModel()
        });

        me.callParent(arguments);

        me.on('selectionchange', me.handleSelectionChange, me);
    },

    beforeDestroy: function() {
        var me = this;

        me.un('selectionchange', me.handleSelectionChange, me);

        me.callParent(arguments);
    },

    buildDocks : function() {
        /**/
    },

    buildSelModel : function() {
        /**/
    },

    handleSelectionChange : function(selModel, selected) {
        var view = selModel.view,
            grid = view.up('gridpanel'),
            btn  = grid.down('button[action=delete]');

        btn.setDisabled(selected.length === 0);
    }
});

Can you see where I used on() and un()? Now, when you render the grid, the listeners you placed in the config object that has an afterrender listener gets executed and if you select a row, the delete button will now enable.

Awesome! Now we have a full functional abstract class that has event listeners that cannot be affected when instantiating a class.

About me

I thought I would start this blog off by introducing myself. Many have talked to me but probably don’t know how I became the man I am today. It was a rough road but here it is, I won’t spend years talking about it, I promise.

Early Years

Born in Iowa City, Iowa USA on February 2, 1984 (on a farm), I moved down to Saint Louis, Missouri USA in 1988 where I have called home ever since. I was a shy, quiet yet adventurous child. I never had lots of friends but kept a small group close. I was into sport, soccer being my favorite and devoted lots of my time practicing which didn’t leave me much time to spend inside playing video games.

Teen Years

Like I said, I was an adventurous child I would go places where I shouldn’t go. I lived in the suburbs of Saint Louis so it’s not like I could get into much trouble. There used to be lots of trails and creeks where I used to ride my bike doing tricks… trying to at least. I stopped playing soccer and decided to tear appart my parent’s $4,000 Compaq. My mother came home with everything spread around the room. Little later I got everything put back together and told her I wasn’t too sure I’d get that back together; this is what started my whole nerdness. I started learning by dissecting so when I got a truck when I turned 16, installing a head unit was a fun experiment. Using the Compaq, I started playing online games and joined an online group. This is where I fell into web design as they needed someone to help and I took on that challenge. Of course it was using Frontpage and Geocities but had to use existing Perl scripts but ditched that for PHP. For the next couple years I would spend 100% of my time within PHP. When I turned 16, I also started working at QuikTrip (convenient store chain around the USA) and thought that was what I was going to do for the rest of my life. It took priority over everything, school included. Growing up the way I did, my work ethic was top notch. Working 15 hours wouldn’t be a problem to me.

In the middle of the teen years, I tried escaping a problem I had. My father and I were close; hunting, fishing, sports were things that we did together a lot. The problem I felt is that we would never express our feelings toward each other. He would just push me to be better and if I didn’t live up to what he expected me to be, I felt he was disappointed in me. My family has a history of depression and I look back and I wish I would have seen this and prevented myself going down that road. I tried to work more and keep myself active but I would have terrible mood swings. The smallest thing would set me off. Alcohol would also play a large roll in all of this. This would go on for the better part of a decade.

Adult Years

After high school, I tried going to Maryville University here in Saint Louis going for a degree in eCommerce. I didn’t mind going to school but QuikTrip always trumped it so I bailed out after half a semester. I would then focus on my career at QuikTrip keeping my hobby of web developing on the side. My father also works at QuikTrip and has been very successful and for the first time I felt like he was proud of my accomplishments at following him in his footsteps. I started moving up and taking on projects but keeping him in the dark about my drinking and depression. Going to work drunk was fine as long as I had cologne to mask the smell and energy drinks to keep me awake as I wouldn’t sleep. I stayed away from pills or marijuana and have never tried that; I take pride in this actually.

I haven’t talked much about females in my life as they weren’t really my priority. Yes, I dated and lost my virginity at age 16 but I just didn’t really care about them. After high school they played more of a role. I always seemed to get good looking girls but they would use me because working at QuikTrip I made great money. I built a house, had a truck, car (1994 Ford Mustang 5.0), and a motorcycle (Kawasaki Ninja 600R) all before I could legally drink. Started building my house when I was 19. I would do anything for the girl in my life but looking back, it seems they took advantage of me. Maybe not their fault as I let them. This would not help my depression and confidence. This eventually would teach me about myself and help me later on.

When I was 22, one night waking up in my own vomit, I decided to stop drinking. After that decision, I would only drink socially. I still got drunk once in a while but wouldn’t even be close to drinking like I used to. I went from drinking almost every waking minute to only having a couple here and there. This self control really made myself start taking a long look at what kind of man I was growing up to be. I started taking more action to improve myself and I would have to hit rock bottom and rebuild myself. I quit QuikTrip, foreclosed on my house, moved back in with my parents. Was out of work for 2 months before I started working at Sam’s Club. I was seasonal but after 2 weeks turned full-time. When I start a new job, I work very hard to make myself a crucial asset to my employer. Started making my way up but saw some questionable things being done by management (TVs went missing, favoritism, etc) so I stepped down and kind of was just living day by day. I turned to my hobby of web developing and started contracting. This was just a side job and never really took off.

Love of my life :)

Early 2008 my mother went to visit one of her long time friends. They used to work next door to each other for many many years at the U.S. Department of Veterans Affairs but in 2007 my mother’s friend got a divorce and moved to Florida to pursue a different job within the U.S. Department of Veterans Affairs and her daughter moved down a couple months later. As my mother was down there, her daughter (Danielle Collins) started texting me and we hit it off right away. 2 months later on May 3rd, over the phone and hundreds of miles away, I asked Danielle if she would be my girlfriend. About every other month, one of us would fly to the other to actually see each other, when we were away from each other, Skype had to do. Long distance isn’t easy but I do believe it allowed us to really connect and become each other’s best friend. Fast forward to August 2011, after over 3 years of dating we finally decided to make the hard decision of having her quit her job and move in with me. This was a huge and scary step in our relationship but enough was enough with long distance. We have been living together for a few months now and things couldn’t be going better. Sure we have our little arguments ehre and there but the transition from being a thousand miles away from each other to seeing each other each day hasn’t been as hard as I was afraid. I would do anything for her and hope to get engaged this next year as soon as I find a ring that I am proud to give her.

Ext JS/Sencha Years

Around 2004/2005 I started pushing myself to learn more about web developing. I was using Prototype, Scriptaculous and whatever else I could get my hands on. My thirst for knowledge was driving me in a million directions. It wasn’t till very late in 2006 till I heard of this Ext JS and dropped everything and started trying to wrap my head around this. Early 2007 I jumped on the forums asking for help… I was very green. Next couple years my thirst for knowledge really pushed me to learn a lot about Ext JS and people like Jay Garcia, Nige “Animal” White, Shea “VinylFox” Fredricks, Condor really helped me out. It wasn’t till 2010 until I started getting some traction after helping with the book Ext JS in Action authored by Jay Garcia and some projects. People started coming to me for work so things were looking up. October 2010 I had a full-time opportunity as a web developer so I quit Sam’s Club to pursue web developing as a career. The guy I was working for didn’t like my coding style so he made me code like him. After 3 months of working for him and not liking it, I had another opportunity and took it. I like the guy I was working for, I can work from home, and the pay was great compared to what I was making. In a matter of about 4 months, my pay quadrupled! I thought I would work there for a long time but then I got an email from Ed Spencer at Sencha. At first, I was reluctant because I felt quite loyal to my current boss but I decided to give it a shot so I was flown out to Redwood City, CA USA for my interview. I then talked to Jeff Hartley who seemed very happy to speak with me and decided to offer me a job. I went back home and struggled to make a decision. After talking to family and friends, I decided that it was in my best interest to accept Sencha’s offer and handed in a one month notice to my current boss so that I could finish up things and he could find my replacement.

Joining Sencha in March of 2011 as part of the Professional Services team, I quickly became a bit of a star (self proclaimed). Not being cocky but I could now show my talents off on a larger scale and for many peers who actually understand what is coded. My first assignment in Sencha was working at a certain client (cannot be named) working with Doug Hendricks and Jack Ratcliff who also work at Sencha on the Professional Services team. Doug was traveling a lot but Jack worked locally with me so I became close to working with him… enjoyed bouncing ideas off him and just talking with him on a daily basis. Jack moved on to another project so it was just Doug and I so I was by myself onsite. As of October 21st, I moved on to be the Senior Forum Manager (I got to pick my own title :) ).

That brings us up to today! You probably have started seeing me spam the forums! My mission is to help people learn, not just give answers. I want to guide people to the answer so I’m sorry if you expect example code but that’s not really going to help you grow as a Sencha developer.

Sorry if it was a long post but I appreciate you reading it and getting to know me. I hope to talk to you via Twitter or on the Forums but my true wish is to be able to attend meetups and conferences to meet you in person.

Help with cleanup

We are only in the developer preview stages of Sencha Touch 2 but we are already seeing so many great things. Performance in Android is superb. Scrolling is so native feeling that users won’t really be able to tell it’s really just a web page. Orientation changing is faster than the actual browser. The list goes on and on but I just stumbled on something that will help you clean up after your defined components.

Lots of times, we as developers set references onto components to keep track of things. We now can use the config Object with the getters and setters which is very useful I have to admit. But sometimes that’s just a bit much for what we need. We just want to set a reference and refer to it whenever we want but the problem with this is it can leak memory. So what we would do is either listen for the destroy event or use one of the destroy methods and call the superclass. But what if Sencha Touch as a framework can take care of it? Enter the referenceList.

Every subclass of Ext.AbstractComponent gets an Array placed as referenceList. All this is is an Array of Strings which are references on the component. You will see that the referenceList Array will have ‘element’ and sometimes ‘innerElement’ (depending on if it is an Ext.Container or subclass). When the component is destroyed, the destroy method will iterate over the referenceList Array, execute the destroy method on that reference and then delete it:

        // Destroy all element references
        for (i = 0,ln = referenceList.length; i &lt; ln; i++) {
            reference = referenceList[i];
            this[reference].destroy();
            delete this[reference];
        }

Now you can see the comment says that it will destroy all element references but technically you can put anything in there that has a destroy method. Very simple to clean up your references. Let’s look at an example…

Say you want a fullscreened Ext.Container but you need to detect when that Ext.Container‘s size changes. By default, Ext.Container doesn’t monitor it’s own size so you have to initialize your own Ext.util.SizeMonitor in order to do this. I will caution you, Ext.util.SizeMonitor adds in overhead so don’t go crazy adding it to everything. This is an example of a subclass that does just this:

Ext.define('MyContainer', {
    extend : 'Ext.Container',

    config : {
        fullscreen : true
    },

    initialize: function() {
        var me      = this,
            refList = me.referenceList;

        me.sizeMonitor = Ext.create('Ext.util.SizeMonitor', {
            element  : me.element,
            callback : me.onSizeChange,
            scope    : me
        });

        me.on('painted', 'onPainted', me, { single : true });

        me.callParent();
    },

    onPainted: function(cmp) {
        cmp.sizeMonitor.refresh();
    },

    onSizeChange: function() {
        this.fireEvent('sizechanged', this);
    }
});

Couple things I want to point out here. First, you can see we are placing a reference to the Ext.util.SizeMonitor instance to this.sizeMonitor. Second, you have to execute the refresh method on the Ext.util.SizeMonitor instance when the component has been painted, this is what will make the size change be picked up. This may be better suited for the config Object to get the getter and setter but it’s just an example for this blog post. So right now we have a fully working example with a reference that could be a memory leak, we could listen for the ‘destroy’ event and clean it up ourselves but there is a built in way to do it as mentioned before, the referenceList Array. So after you set the reference, we just need to push a String to the referenceList Array and it will automatically be cleaned up for us:

Ext.define('MyContainer', {
    //..

    initialize: function() {
        var me      = this,
            refList = me.referenceList;

        me.sizeMonitor = Ext.create('Ext.util.SizeMonitor', {
            element  : me.element,
            callback : me.onSizeChange,
            scope    : me
        });
        refList.push('sizeMonitor');

        me.on('painted', 'onPainted', me, { single : true });

        me.callParent();
    },

    //...
});

That simple! But remember, it must have that destroy method or else you will get a JavaScript error as there is no check if a destroy method is present. Kind of wish there was for other references but it’s not really what this was meant for.

Enjoy all the Sencha Touch 2 goodness!