Fusioncube

The online journey of a technophile, by Steve Brownlee

I’ll admit that I’m very fortunate. I work in a field that is my true passion.  I am a technologist, and more specifically, a software architect. I also work for a great company that allows me to be creative, efficient, and impactful.

However, a recent article I read just made me realize that my passion has been eaten away by something else.

I used to work late… just because. If I was working on some particularly hairy algorithm, or software problem, I would work until it was complete. I got a rush out of it, and a deep sense of satisfaction that I could turn something complex into something elegantly simple.

I would go home and read technical books, online articles, and samples about up-and-coming languages or tools. I would be constantly writing sample applications in new languages, or playing around with a new database schema editor or programming environment. I would also join discussion groups, and attend local user group meetings just to meet and talk with people who shared my passion.

Most of that is gone now.

Now, my overriding thought is my two girls. They are my passion. Growing up and in my early adulthood, I knew I wanted a family and wanted to be the best father I could be. I thought about how I would raise my children to be competent, intelligent, resourceful adults.

Now that I am actually a father, I’ve realized two things:

  1. Even though I knew it would be a lot of work, I had no idea how much work is involved in raising children.
  2. I love it. I truly feel like I was made to be a father to my kids. Yeah it’s hard work, but I love every funny, whiny, screaming, giggling, sticky-fingered, cuddly, exasperating, exhausting, exhilarating minute of it.

Gone are the days of coming home and reading books and magazines about technology. Now I come home and am welcomed by two little girls who scream, “Daddy!! You’re home!!” and want hugs and kisses.

How can you not be passionate about that?

Published on Wednesday, Jul 28,2010 | 4 Comments

A few weeks ago I was at a gathering of like-minded technologists in my area, and I struck up a quick (thankfully) conversation with a fellow who, in all seriousness, labeled himself a Social Media Ninja. He just let it hang there for a second, waiting for the expected, and inevitable, question, “What is a Social Media Ninja?”

I’ll do my best to correctly paraphrase his response.

Apparently, a Social Media Ninja is someone who has 5000 followers on their Twitter account, shares links to articles that other people post throughout the day, and has an active Facebook fan page.

Huh.

So I guess my 15-year-old niece is a Social Media Ninja. Perhaps she should be out there trying to get the same jobs that this tool – I mean Ninja – is trying to procure.

Not once did he talk about how these amazing, super-human like powers could possibly help a business retain, or gain, customers. He failed to mention that he could affect a company’s revenue stream in any way shape or form. Apparently he just wants someone to hire him so that he can create a Twitter account, and a Facebook fan page and sit there and talk to people all day.

No strategy. No plan. Sorry, that means no results.

However, he does have something cool to put on his business cards.

Published on Friday, Jul 23,2010 | 6 Comments

In an ExtJS ComboBox, it’s fairly easy to implement a search feature where given the user’s entry, you can return a list of possible matches. I outline this mechanism in Sencha ExtJS: Simple Autocomplete Example.

However, recent user feedback was, “If I know the unit I’m looking for, why can’t I just type it in and hit ENTER and skip the whole search feature to find the one I need?”

Doh.

Yes, I was making the users wait – even if for 1 second – for a list of possible matches to be displayed, when 90% of the time they know which one they want to open.

Luckily, I was able to briefly look at the documentation for ComboBox and find out how to accomplish this. You need to set the enableKeyEvents config property to true, and then hook into the keypress event and check for the user pressing the ENTER (or RETURN) key. When the ENTER key is pressed, prevent the query from being executed, and open the item the user entered.

var WidgetSearch = new Ext.form.ComboBox({
    minChars:           3,
    loadingText:        '',
    itemSelector:       'div.search-item',
    triggerClass:       'x-form-search-trigger',
    applyTo:            'search-field',
    enableKeyEvents:  true,
    store: new Ext.data.Store({
        proxy: new Ext.data.HttpProxy({url: 'widgets.cfm'}),
        reader: new Ext.data.JsonReader({
            root:           'data',
            totalProperty:  'recordcount'
        }, [
            {name: 'widget_number', type: 'string'},
            {name: 'widget_name', type: 'string'}
        ])
    }),
    tpl: new Ext.XTemplate(
        '<tpl for="."><div class="search-item">',
            '{widget_number} - {widget_name}',
        '</div></tpl>'
    ),
    onSelect: function(record){
        document.location.href = 'displayWidgetDetails.cfm&amp;wid=' + record.data.widget_number;
    },
    listeners:
    {
        // Hook into the keypress event to detect if the user pressed the ENTER key
        keypress: function(comboBox, e){
            if (e.getCharCode() == e.ENTER) {
                // Prevent the default query action since the user
                // believes she has entered a proper widget number
                comboBox.on('beforequery', function(q){q.cancel=true;},this);

                // Redirect browser to widget detail view
                document.location.href = 'displayWidgetDetails.cfm&amp;wid=' + WidgetSearch.getValue();
            }
        }
    }
});
Published on Wednesday, Jul 21,2010 | 1 Comment

A Sencha ExtJS EditorGridPanel automatically visually marks a cell as dirty when a user modifies the value, but that’s it. If you want to know if a row is dirty and take an action based upon that knowledge, you’re on your own.

Since I needed this functionality, I took a stab at it today, and here’s my simplistic example of how to do it.

First, I create a global variable named editedRow which will get updated when the afteredit event is fired on the GridPanel.

var editedRow;

var AutoGrid = new Ext.grid.EditorGridPanel({
    // Properties clipped for article;
    // view example for full code
});

// After any field is edited, make the row dirty
AutoGrid.on('afteredit', function(){
    if (!editedRow){
        editedRow = AutoGrid.getSelectionModel().getSelections();
    }
}, this);

Now that I’ve stored which row is dirty, every time the user clicks on another cell, I check a) there is a dirty row, and b) if the active row is the dirty row.

// Any time the user mouse downs on a cell,
// check to see if there are any dirty rows
AutoGrid.on('cellmousedown', checkForChanges, this);

function checkForChanges(){
    if (!editedRow){
        return true;      // No dirty rows
    } else {
        var selectedRow = AutoGrid.getSelectionModel().getSelections();
        var selectedRecord = selectedRow[0].data;
        var editedRecord;

        editedRecord = editedRow[0].data;

        if (selectedRecord.model != editedRecord.model){
            // Alert the user to save changes
            // See example for full code
        }
    }
}

Then if there is a dirty row, I can prompt the user and ask it to save its changes before editing another row.

View Dirty Row Example

Published on Tuesday, Jul 20,2010 | 0 Comments

Man this took a long time to figure out.

Ok, inside a Sencha ExtJS DataGrid, I have assigned a ComboBox as the editor for one of the columns populated with its own Store of items. I’ve got a ColdFusion Component returning a query object, which is then converted into JSON with the ajaxCFC class.

var ItemCode = Ext.data.Record.create([
       {name: 'item_id', type: 'int'}
       {name: 'item_code', type: 'string'}
]);

var ItemCodesStore = new Ext.data.Store({
    autoLoad:false,
    proxy: new Ext.data.MemoryProxy(),
    reader: new Ext.data.JsonReader({ root: 'data'; }, ItemCode)
});

// Snippet from ColumnModel of DataGrid
header: 'Code',
dataIndex: 'existingCode',
width: 70,
editor: new Ext.form.ComboBox({
   mode: 'local',
   displayField: 'item_code',
   valueField: 'item_id',
   store: ItemCodesStore
})

This is straightforward code. The column represents the existingCode value in the DataGrid’s store, and when the user clicks on an individual cell, a ComboBox is rendered with possible values stored in ItemCodesStore.

My problem is that I want the item_code value displayed at all times. By default, when a user selects an item from the ComboBox, the item_id value will be displayed, because even though I have set displayField:’item_code’ in the ComboBox, the DataGrid has no knowledge of this, and always shows the valueField.

What I had to do was write a custom renderer for that column that does a search in the ItemCodes store for a matching item_id and return the item_code to be rendered instead.

function CodeRenderer(val){
    var matching = ItemCodesStore.queryBy(
                      function(rec,id){
                         return rec.item_id == val;
                      });
    return (matching.items[0]) ? matching.items[0].data.item_code : '';
};

// Snippet from ColumnModel of DataGrid
header: 'Code',
dataIndex: 'existingCode',
width: 70,
renderer: CodeRenderer,
editor: new Ext.form.ComboBox({
   mode: 'local',
   displayField: 'item_code',
   valueField: 'item_id',
   store: ItemCodesStore
})
Published on Tuesday, Jul 20,2010 | 1 Comment

Latest Tweets

  • Watch video on this page to see a quick shot my family's biz and a heapin' helpin' of Pittsburghese - http://bit.ly/aMxuLN
  • Ever wonder how insignifcant the Earth is on a cosmic scale? http://bit.ly/PV4o
  • How did I miss this highlight??? Hasek takes out Gaborik http://su.pr/1KZtN2
  • Rooted & upgraded my HTC Hero w/#Froyo. Holy shit is it faster and have improved features. Painless, too. http://bit.ly/cBjvuH #fusprint
  • @Antipimp You will do what Father Jobs tell you to do, peon.