Ext JS Layouts: Messenger Window, Part 1

Today I start a series of posts dedicated to Ext JS layouts.  I will initiate this series creating a messenger-like interface that will have an area for displaying contacts and their statuses, and an area for displaying a conversation.  The goal is not to implement a messenger system, but rather to walk through the steps required for building a user interface, and end up with some code that you can use as a learning tool.

In this post I will focus on the contacts area of my messenger-like interface. I will use a window as the container.  Inside this window I will place a number of controls that will satisfy these requirements:

  • Display the name, avatar and status of the current user
  • Provide the user with a means to change her current status, selecting from available, busy, away or appear offline
  • Provide the user with a means to share a quick message and show the music she’s listening to
  • Provide the user with a means to navigate to her profile, contact card, or space
  • Display a the user’s contacts, organized by favorites, available and offline

In future posts I will enhance and refine this interface.  By the end of this post, I will have a window that looks like this:

Ext JS tutorial

Looks familiar? :-)

All right. Let’s get started.

The messenger window

I already decided that my container will be a window.  All I need for the moment is a title and the dimensions:

var wnd = new Ext.Window({
    width: 300,
    height: 450,
    layout:'fit',
    title: 'Instant Messenger'
});

And this is how it looks like:

messenger-4

Display the name, avatar and status of the current user

I will use the window’s toolbar to display the name and avatar of the user.  First, I will create the toolbar and use the new button group component to layout the toolbar items in two columns, one for the avatar and one for the user’s name:

var wnd = new Ext.Window({
    width: 300,
    height: 450,
    layout:'fit',
    title: 'Instant Messenger',
    tbar: [{
        xtype: 'buttongroup',
        columns: 2
    }]
});

The avatar and user name go in as toolbar buttons.  I’m making them buttons because I want to allow the user to click on them and perform some tasks. This is the window now:

var wnd = new Ext.Window({
    width: 300,
    height: 450,
    layout:'fit',
    title: 'Instant Messenger',
    tbar: [{
        xtype: 'buttongroup',
        columns: 2,
        items: [{ xtype: 'button', scale: 'large', iconCls: 'icon-user', rowspan: 2 },
            { xtype: 'splitbutton', text: 'Jorge (available)' }]
        }]
});

It’s starting to look good:

messenger-5

Provide the user with a means to change her current status

To allow for status changes, I will add a menu to the username button.  Here’s the code:

var wnd = new Ext.Window({
    width: 300,
    height: 450,
    layout:'fit',
    title: 'Instant Messenger',
    tbar: [{
        xtype: 'buttongroup',
        columns: 2,
        items: [{ xtype: 'button', scale: 'large', iconCls: 'icon-user', rowspan: 2 },
            { xtype: 'splitbutton', text: 'Jorge (available)',
                menu: [{ text: 'Available', iconCls: 'ico-sts-available' },
                        { text: 'Busy', iconCls: 'ico-sts-busy' },
                        { text: 'Away', iconCls: 'ico-sts-away' },
                        { text: 'Appear Offline', iconCls: 'ico-sts-offline'}]
        }]
    }]
});

And this is how it looks:

messenger-6

Provide the user with a means to share a quick message and show the music she’s listening to

For this, I will use a split button, placed immediately below the username button:

var wnd = new Ext.Window({
    width: 300,
    height: 450,
    layout:'fit',
    title: 'Instant Messenger',
    tbar: [{
        xtype: 'buttongroup',
        columns: 2,
        items: [{ xtype: 'button', scale: 'large', iconCls: 'icon-user', rowspan: 2 },
            { xtype: 'splitbutton', text: 'Jorge (available)',
                menu: [{ text: 'Available', iconCls: 'ico-sts-available' },
                        { text: 'Busy', iconCls: 'ico-sts-busy' },
                        { text: 'Away', iconCls: 'ico-sts-away' },
                        { text: 'Appear Offline', iconCls: 'ico-sts-offline'}]
            },{ xtype: 'splitbutton', text: 'Share a quick message',
                menu: [{ text: 'Show what I am listening to'}]
         }]
    }]
});

messenger-7

Provide the user with a means to navigate to her profile, contact card, or space

I will add this feature in the form of a menu attached to the avatar button:

var wnd = new Ext.Window({
    width: 300,
    height: 450,
    layout:'fit',
    title: 'Instant Messenger',
    tbar: [{
        xtype: 'buttongroup',
        columns: 2,
        items: [{ xtype: 'button', scale: 'large', iconCls: 'icon-user', rowspan: 2,
        menu: [{ text: 'Show profile' }, { text: 'View contact card' },
               { text: 'Go to your space'}]
            },{ xtype: 'splitbutton', text: 'Jorge (available)',
                menu: [{ text: 'Available', iconCls: 'ico-sts-available' },
                        { text: 'Busy', iconCls: 'ico-sts-busy' },
                        { text: 'Away', iconCls: 'ico-sts-away' },
                        { text: 'Appear Offline', iconCls: 'ico-sts-offline'}]
            },{ xtype: 'splitbutton', text: 'Share a quick message',
                menu: [{ text: 'Show what I am listening to'}]
         }]
    }]
});

This is how the menu looks:

messenger-8

Display a the user’s contacts, organized by favorites, available and offline

The contacts will be shown with a treview.  I will create an invisible root node and three branch nodes named Favorites, Available and Offline.  The user’s contacts will be leaf nodes under these branches.

First, I add the tree to the window:

items: [{ xtype: 'treepanel',
    id: 'contacts-tree',
    border: false,
    useArrows: true,
    autoScroll: true,
    animate: true,
    containerScroll: true,
    bodyCssClass: 'tree-body',
    dataUrl: 'messenger.aspx',
    requestMethod: 'get',
    rootVisible: false,
    root: {
        nodeType: 'async',
        text: 'My Reporting Project',
        draggable: false,
        id: 'root-node'
}}]

Then, below the window definition, I add the favorites, available and offline branch nodes, as well as a few dummy contacts.  I use the afterrender event to acquire a reference to the root node and then add child nodes to it:

var tree = Ext.getCmp('contacts-tree');
tree.on('afterrender', function(loader, node) {
    var root = tree.getRootNode();
    var node = root.appendChild({ id: 'favorites', text: 'Favorites', expanded: true, iconCls: 'ico-fav' });
    node.appendChild({ text: 'Susie', leaf: true, iconCls: 'ico-sts-available' });
    node.appendChild({ text: 'Lara', leaf: true, iconCls: 'ico-sts-away' });

    node = root.appendChild({ text: 'Available', expanded: true, iconCls: 'ico-grp-available' });
    node.appendChild({ text: 'Jonh', leaf: true, iconCls: 'ico-sts-busy' });
    node.appendChild({ text: 'Lara', leaf: true, iconCls: 'ico-sts-away' });
    node.appendChild({ text: 'Susie', leaf: true, iconCls: 'ico-sts-available' });

    node = root.appendChild({ text: 'Offline', expanded: true, iconCls: 'ico-grp-offline' });

})

And the window looks just the way I had planned:

Ext JS window

This does it for now.  In the next post of this series I will continue adding features to this contacts window.

Downloads

Download the full sample from my downloads page.

E-mail   Permalink    Comments(2)   Trackback

Tags:

Comments

By Frank  on Monday, October 19, 2009

Hi,Jorge: I just translated the article into Chinese, you can download from this url:

http://w45438.s48.mydiscuz.com/temp/messenager.zip

I'll find another way to post this article!

By Jorge  on Monday, October 19, 2009

@Frank

Thank you, I hope the article helps!