Today I start a series of posts dedicated to ExtJS 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:
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:
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:
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:
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'}] }] }] });
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:
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:
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: ExtJs_Messenger_Layout_1.zip
Leave a Comment