Sencha Touch: Layouts Revisited

Exclusive offer: get 50% off this eBook here
Sencha Touch Mobile JavaScript Framework

Sencha Touch Mobile JavaScript Framework — Save 50%

Build web applications for Apple iOS and Google Android touchscreen devices with this first HTML5 mobile framework book and ebook

€20.99    €10.50
by Bryan P. Johnson John Earl Clark | February 2012 | Open Source

In this article by John E. Clark and Bryan P. Johnson, authors of Sencha Touch Mobile JavaScript Framework, we will examine the layout configuration option and how it affects each of the components.

Specifically, we will cover the following points:

  • The base component class
  • Layouts revisited

 

(For more resources on this topic, see here.)

The reader can benefit from the previous article on The Various Components in Sencha Touch.

The base component class

When we talk about components in Sencha Touch, we are generally talking about buttons, panels, sliders, toolbars, form fields, and other tangible items that we can see on the screen. However, all of these components inherit their configuration options, methods, properties, and events from a single base component with the startlingly original name of component. This can obviously lead to a bit of confusion, so we will refer to this as Ext.Component.

One of the most important things to understand is that you will never actually use Ext.Component directly. It is simply used as a building block for all of the other components in Sencha Touch. However, it is important to be familiar with the base component class, because anything it can do, all the other components can do. Learning this one class can give you a huge head start on everything else. Some of the more useful configuration options of Ext.Component are as follows:

  • border
  • cls
  • disabled
  • height/width
  • hidden
  • html
  • margin
  • padding
  • scroll
  • style
  • ui

Ext.Component also contains a number of useful methods that will allow you to get and set properties on any Sencha Touch component. Here are a few of those methods:

  • addCls and removeCls: Add or remove a CSS class from your component.
  • destroy: Remove the component from memory.
  • disable and enable: Disable or enable the component (very useful in forms).
  • getHeight, getWidth, and getSize: Get the current height, width, or size of the component. Size returns both height and width. You can also use setHeight, setWidth, and setSize, to change the dimensions of your component.
  • show and hide: Show or hide the component.
  • setPosition: Set the top and left values for the component.
  • update: Update the content area of a component.

Unlike our configuration options, methods can only be used once the component is created. This means we also need to understand how to get the component itself before we can begin using the methods. This is where the Ext class comes into play.

The Ext object and Ext.getCmp()

The Ext object is created, by default, when the Sencha Touch library is loaded. This object has methods that are used to create our initial application and its components. It also allows us to talk to our other components after they have been created. For example, let's take a look at a code example:

new Ext.Application({
name: 'TouchStart',
launch: function() {
var hello = new Ext.Container({
fullscreen: true,
html: '<div id="hello">Hello World</div>',
id: 'helloContainer'
});
this.viewport = hello;
}
});

The configuration option, id: 'helloContainer' will allow us to grab the container, later on, using our Ext class and the method getCmp().

For example, we can add the following code after this.viewport = hello;:

var myContainer = Ext.getCmp('helloContainer');
myContainer.update('Hello Again!');

By using Ext.getCmp, we get back the component with an id value of helloContainer, which we then set to our variable myContainer. Using this method returns an actual component, in this case a container.

Since we get this object back as a container component, we can use any of the methods that the container understands. For our example, we used the update() method to change the content of the container to 'Hello Again!'. Typically, these types of changes will be generated by a button click and not in the launch function. This example simply shows that we can manipulate the component on the fly even after it gets created.

The ID configuration
It's a good idea to include an id configuration in all of your components. This makes it possible to use Ext.getCmp() to get to those components, later on, when we need them. Remember to keep the ID of every component unique. If you plan on creating multiple copies of a component, you will need to make sure that a unique ID is generated for each copy.

The Ext.getCmp() method is great for grabbing Sencha Touch components and manipulating them.

 

Layouts revisited

Layouts are another area we need to expand upon. When you start creating your own applications, you will need a firm understanding of how the different layouts affect what you see on the screen. To this end, we are going to start out with a demonstration application that shows how the different layouts work.

For the purposes of this demo application, we will create the different components, one at a time, as individual variables. This is done for the sake of readability and should not be considered the best programming style. Remember that any items created this way will take up memory, even if the user never views the component.

var myPanel = new Ext.Panel({ ...

It is always a much better practice to create your components, using xtype attibutes, within your main container:

items: [{ xtype: 'panel', ...

This allows Sencha Touch to render the components as they are needed, instead of all at once when the page loads.

The card layout

To begin with, we will create a simple card layout:

new Ext.Application({
name: 'TouchStart',
launch: function() {
var layoutPanel = new Ext.Panel({
fullscreen: true,
layout: 'card',
id: 'layoutPanel',
cardSwitchAnimation: 'slide',
items: [hboxTest]
});
this.viewport = layoutPanel;
}
});

This sets up a single panel with a card layout. The card layout arranges its items similar to a stack of cards. Only one of these cards is active and displayed at a time. The card layout keeps any additional cards in the background and only creates them when the panel receives the setActiveItem() command.

Each item in the list can be activated by using setActiveItem() and the item number. This can be a bit confusing, as the numbering of the items is zero-indexed, meaning that you start counting at zero and not one. For example, if you want to activate the fourth item in the list, you would use:

layoutPanel.setActiveItem(3);

In this case, we are starting out with only a single card/item called hboxTest. We need to add this container to make our program run.

The hbox layout

Above the line that says var layoutPanel = new Ext.Panel({, in the preceding code, add the following code:

var hboxTest = new Ext.Container({
layout: {
type: 'hbox',
align: 'stretch'
},
items: [{
xtype: 'container',
flex: 1,
html: 'My flex is 1',
margin: 5,
style: 'background-color: #7FADCF'
}, {
xtype: 'container',
flex: 2,
html: 'My flex is 2',
margin: 5,
style: 'background-color: #7FADCF'
}, {
xtype: 'container',
width: 80,
html: 'My width is 80',
margin: 5,
style: 'background-color: #7FADCF'
}]
});

This gives us a container with an hbox layout and three child items.

Child and parent
In Sencha Touch, we often find ourselves dealing with very large arrays of items, nested in containers that are in turn nested in other containers. It is often helpful to refer to a container as a parent to any items it contains. These items are then referred to as the children of the container.

The hbox layout stacks its items horizontally and uses the width and flex values to determine how much horizontal space each of its child items will take up. The align: 'stretch' configuration causes the items to stretch to fill all of the available vertical space.

If we run the code now, we should see this:

Sencha Touch Mobile JavaScript Framework

You should try adjusting the flex and width values to see how it affects the size of the child containers. You can also change the available configuration options for align (center, end, start, and stretch), to see the different options available. Once you are finished, let's move on and add some more items to our card layout.

 

Sencha Touch Mobile JavaScript Framework Build web applications for Apple iOS and Google Android touchscreen devices with this first HTML5 mobile framework book and ebook
Published: February 2012
eBook Price: €20.99
Book Price: €34.99
See more
Select your format and quantity:

 

(For more resources on this topic, see here.)

The vbox layout

Above our previous var hboxTest = new Ext.Container({ code, add the following:

var vboxTest = new Ext.Container({
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'container',
flex: 1,
html: 'My flex is 1',
margin: 5,
style: 'background-color: #7FADCF'
}, {
xtype: 'container',
flex: 2,
html: 'My flex is 2',
margin: 5,
style: 'background-color: #7FADCF'
}, {
xtype: 'container',
height: 80,
html: 'My height is 80',
margin: 5,
style: 'background-color: #7FADCF'
}]
});

This code is virtually identical to our previous hbox code, a container with three child containers. However, this parent container uses layout: vbox, and the third child container in the items list uses height instead of width. This is because the vbox layout stacks its items vertically and uses the values for height and flex to determine how much space the child items will take up. In this layout, the align: 'stretch' configuration causes the items to stretch to fill the horizontal space.

Now that we have our vbox container, we need to add it to the items in our main layoutContainer. Change the items list in layoutContainer to say the following:

items: [hboxTest, vboxTest]

If we run the code now, it's going to look exactly the same as before. This is because our card layout on layoutContainer can only have one active item. You can set layoutContainer to show our new vbox by adding the following configuration to our layoutContainer:

activeItem: 1,

Remember that our items are numbered starting with zero, so item 1 is the second item in our list: items: [hboxTest, vboxTest].

You should now be able to see the vbox layout for our application:

Sencha Touch Mobile JavaScript Framework

As with the hbox, you should take a moment to adjust the flex and width values and see how it affects the size of the containers. You can also change the available configuration options for align (center, end, start, and stretch), to see the different options available. Once you are finished, let's move on and add some more items to our card layout.

The fit layout

The fit layout is the most basic layout and it simply fits any child items to the parent container. While this seems pretty basic, it can also have some unintended consequences, as we will see in our example.

Above our preceding var vboxTest = new Ext.Container({ code, add the following:

var fitTest = new Ext.Container({
layout: 'fit',
items: [{
xtype: 'button',
ui: 'decline',
text: 'Do Not Press'
}]
});

This is a single container with a fit layout and a button. Now, all we need to do is set the activeItem configuration on our main layoutContainer component by changing activeItem: 1 to activeItem: 2.

If you reload the page now, you will see what we mean by unintended consequences:

Sencha Touch Mobile JavaScript Framework

As you can see, our button has expanded to fill the entire screen. We can change this by declaring a specific height and width for the button (and any other items we place in this container). However, fit layouts tend to work best for a single item that is intended to take up the entire container. This makes them a pretty good layout for child containers, where the parent container controls the overall size and position.

Let's add a bit of complexity to our application and see how this might work.

Adding complexity

For this example, we are going to create a nested container and add it to our card stack. We will also add some buttons to make switching the card stack easier.

Our two new containers are variations on what we already have in our current application. The first is a copy of our hbox layout with a few minor changes:

var complexTest = new Ext.Container({
layout: {
type: 'vbox',
align: 'stretch'
},
style: 'background-color: #FFFFFF',
items: [{
xtype: 'container',
flex: 1,
html: 'My flex is 1',
margin: 5,
style: 'background-color: #7FADCF'
},
hboxTest2, {
xtype: 'container',
height: 80,
html: 'My height is 80',
margin: 5,
style: 'background-color: #7FADCF'
}]
});

You can copy and paste our old vboxTest code and change the first line to say complexTest instead of vboxTest. You will also need to remove the second container in our items list (parentheses and all) and replace it with hboxTest2. This is where we will nest another container with its own layout.

Now, we need to define hboxTest2, by copying our previous hboxTest code, and make a few minor changes. You will need to paste this new code up above where you placed the complexTest code, otherwise you will get errors when we try to use hboxTest2, before we actually define it:

var hboxTest2 = new Ext.Container({
layout: {
type: 'hbox',
align: 'stretch'
},
flex: 2,
style: 'background-color: #FFFFFF',
items: [{
xtype: 'container',
flex: 1,
html: 'My flex is 1',
margin: 5,
style: 'background-color: #7FADCF'
}, {
xtype: 'container',
flex: 2,
html: 'My flex is 2',
margin: 5,
style: 'background-color: #7FADCF'
}, {
xtype: 'container',
width: 80,
html: 'My width is 80',
margin: 5,
style: 'background-color: #7FADCF'
}]
});

After you paste in the code, you will need to change the variable name to hboxTest2, and we will need to add a flex configuration to the main parent container. Since this container is nested within our vbox container, the flex configuration is needed to define how much space hboxTest2 will occupy.

Before we take a look at this new complex layout, let's make our lives a bit easier by adding some buttons to switch between our various layout cards.

Locate layoutPanel and, underneath, where we define the active item, add the following code:

dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
text: 'hbox',
handler: function() {
var cards = Ext.getCmp('layoutPanel');
cards.setActiveItem(0);
}},{
text: 'vbox',
handler: function() {
var cards = Ext.getCmp('layoutPanel');
cards.setActiveItem(1);
}
},{
text: 'fit',
handler: function() {
var cards = Ext.getCmp('layoutPanel');
cards.setActiveItem(2);
}
},{
text: 'complex',
handler: function() {
var cards = Ext.getCmp('layoutPanel');
cards.setActiveItem(3);
}
}],
}],

This code adds a toolbar to the top of our layoutPanel, with a button for each of our layout cards.

Each button has a text configuration, which serves as the button's title, and a handler configuration. The handler configuration defines what happens when the button is clicked. For each of our buttons, we grab the layoutPanel, using Ext.getCmp():

var cards = Ext.getCmp('layoutPanel');

This lets us manipulate our variable cards, just as we would manipulate any other panel with a card layout. We can then set the active item in each case by using the following:

cards.setActiveItem(x);

The x, in this case, would be replaced by the index of the item we want to activate (remember that these go in order, starting with zero and not one).

Notice that we also leave the configuration option for activeItem in our layoutPanel component. This will control which item is displayed when our application starts.

If you refresh the page, you should be able to click through the buttons and see each of our layouts, including the new complex layout.

Sencha Touch Mobile JavaScript Framework

As you can see from this example, our vbox layout splits the window into three rows. The hbox layout, in the second row, splits it into three columns. Using these types of nested layouts makes it pretty easy to create traditional layouts, such as those used in e-mail or social networking applications.

For example, a typical e-mail application can be conceptually broken down into the following:

  • An application container with a Toolbar and a single container called Main with a fit layout.
  • The Main container will have an hbox layout and two child containers called Left and Right.
  • The Left container will have a flex of 1 and a vbox layout. It will have two child containers called Mailboxes (with a flex of 3) and Activity (with a flex of 1).
  • The Right container will have a flex of 3 and a vbox layout. It will also have two child containers called Messages (with a flex of 1) and Message (with a flex of 2).

Sencha Touch Mobile JavaScript Framework

Summary

In this article, we began with a look at the base component called Ext.Component. We also showed how to grab a component after it gets created, so we can manipulate it as needed. We then explored the layout for containers in more detail, showing how it affects the child items inside the container.


Further resources on this subject:


Sencha Touch Mobile JavaScript Framework Build web applications for Apple iOS and Google Android touchscreen devices with this first HTML5 mobile framework book and ebook
Published: February 2012
eBook Price: €20.99
Book Price: €34.99
See more
Select your format and quantity:

About the Author :


Bryan P. Johnson

Bryan P. Johnson is a graduate of the University of Georgia. He went to work for MindSpring Enterprises in late 1995, where he met his co-author John Earl Clark. At MindSpring and later, EarthLink; Bryan served in multiple positions for over seven years, including the Director of System Administration and Director of Internal Application Development. After leaving EarthLink, he took some time off to travel before joining John to start Twelve Foot Guru.

Bryan has worked with Sencha's products since the early days of YUI-Ext and has used Sencha Touch since its first betas.

John Earl Clark

John Earl Clark holds a Master's Degree in Human Computer Interaction from Georgia Tech and an undergraduate degree in Music Engineering from Georgia State University. John and his co-author, Bryan Johnson, worked together at MindSpring and later EarthLink, starting out in Technical Support and Documentation, before moving into Application Development and finally management of a small development team. After leaving Earthlink in 2002, John began working independently as a consultant and programmer, before starting Twelve Foot Guru, LLC with Bryan in 2005.

John has been working with Sencha Touch since the first early beta releases. He has also worked with Sencha’s ExtJS since the early days when it was still known as YUI-Ext. John has also written a previous book with Bryan Johnson called Sencha Touch Mobile JavaScript Framework.

When he is not buried in code, John spends his time woodworking, playing guitar and brewing his own beer.

Books From Packt


Sencha Touch Cookbook
Sencha Touch Cookbook

iOS 5 Essentials
iOS 5 Essentials

iPhone User Interface Cookbook
iPhone User Interface Cookbook

HTML5 Mobile Development Cookbook
HTML5 Mobile Development Cookbook

Xcode 4 iOS Development Beginner's Guide
Xcode 4 iOS Development Beginner's Guide

Ext JS 4 Web Application Development Cookbook
Ext JS 4 Web Application Development Cookbook

Core Data iOS Essentials
Core Data iOS Essentials

iPhone JavaScript Cookbook
iPhone JavaScript Cookbook


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software