
The layout system
One of the greatest features of the Ext JS library is the ability to create layouts in an easy way. We can define fixed layouts or fluid layouts using the right classes.
At this point, you know how a container works. We can arrange the children of a container by setting a layout. If we don't define a layout to our containers, by default the auto
layout will be used. In our previous examples, we used the auto
layout and as we could see, the children or HTML are displayed one after another.
There are many available layouts we can use to arrange our components, such as accordions
, cards
, columns
, and so on.
We can find all the available layouts in the Ext.layout.container
package. Go to the documentation and look into the layouts enum
class: http://docs.sencha.com/extjs/5.1/5.1.1-apidocs/#!/api/Ext.enums.Layout.
Here we will see many classes, each representing a type of layout. Some of the most common layouts are:
- The Border layout
- The Fit layout
- The Card layout
- The Accordion layout
- The Anchor layout
The Border layout
The Border layout pides the container space into five regions (multiple panes): north
, south
, west
, east
, and center
. We can place our children in any of the regions, but we are always required to use the center region.
In the following code, we will define the layout as border
. We will also define the center
, west
, and south
regions for the border
layout:
Ext.onReady(function(){ Ext.create('Ext.panel.Panel', { width: 500, height: 300, title: 'Border Layout', layout: 'border', items: [{ xtype: 'panel', title: 'South Region is resizable', region: 'south', // region height: 100, split: true // enable resizing },{ xtype: 'panel', title: 'West Region', region:'west', // region width: 200, collapsible: true, //make panel/region collapsible layout: 'fit', split: true // enable resizing },{ title: 'Center Region', region: 'center', layout: 'fit', margin: '5 5 0 0', html:'<b>Main content</b> goes here' }], renderTo: Ext.getBody() }); });
We have made the West region a collapsible panel. If we click on the small arrow located in the header or in the pision bar, we'll see that the panel will collapse to the left-hand side. Also, we have defined our South panel to be split. This allows us to resize the South panel by dragging the separation bar with our mouse.
Note
You can directly place another component(s) that supports a region in order to avoid over-nesting of components.
The Fit layout
This layout is intended to be used for only one child. It allows us to expand the inner component to the size of the container. The child component takes all the available space in the container component. When the parent is resized, the child size is updated too to fit the new dimensions. Let's make the code for this layout:
Ext.onReady(function(){
var win = Ext.create("Ext.window.Window",{
title: "My first window",
width: 300,
height: 200,
maximizable: true,
layout: "fit",
defaults: {
xtype: "panel",
height: 60,
border: false
},
items: [
{title: "Menu", html: "The main menu"},
{title: "Content", html: "The main content!"}
]
});
win.show();
});
In the previous code, we only added the layout
property. In this case, we're setting a string with the name of the layout, but we can also set an object and define some configurations for the selected layout. In fact, every layout is a class that accepts configurations.
The following screenshot shows how the fit
layout arranges the children of the container component:
As you can see, even though we defined two children components to the window, it only shows one. If we resize the main window, we should see that the Menu panel is expanded to fit the new size of the window.
The Card layout
The Card layout can manage multiple child components, so if we need to create a wizard or display only one component at a time, we should use this layout. This layout extends the fit
layout class, which means that only one component can be visible at any given time and will fill all the available space in the container.
We can also set the initial displayed component by its index using the index from the items
array. And we can move the components easily by calling the next
or prev
method. Let's check out the code for the Card layout:
Ext.onReady(function(){ var win = Ext.create("Ext.window.Window",{ title: "My first window", width: 300, height: 200, maximizable: true, layout: "card",//Step 1 defaults:{ xtype: "panel", height: 60, border: false }, items: [{ title: "Menu", html: "The main menu" },{ title: "Content", html: "The main content!" }] }); win.show(); setTimeout(function(){ win.getLayout().setActiveItem(1); //Step 2 },3000); });
The previous code creates a window
component with two panels. We set the layout of the window to card
in step one.
In step two, we get the layout instance by calling the getLayout
method after 3 seconds and change the initial item using the setActiveItem(1)
method to show the Content panel. We can also use the prev
and next
methods from the layout instance to show the next and previous card.
The Accordion layout
Similar to the Card layout, this layout allows us to show one component at a time in an expandable Accordion style. We will see the header of the inner components and we're going to be able to expand and collapse the components by clicking on their title bars. Let's check the following code for the Accordion layout:
var win = Ext.create("Ext.window.Window",{
title: "My first window",
width: 300,
height: 200,
maximizable: true,
layout: "accordion",
defaults: { xtype: "panel" },
items:[
{title: "Menu", html: "The main menu" },
{title: "Content", html: "The main content!" },
{title: "3rd Panel", html: "Content here...!" }
]
});
Modifying the previous code, we have only changed/defined the Accordion layout and added a new panel to the items
array. We'll see something like the following screenshot:
When using the Accordion layout, we'll see only one panel expanded at a time. The expanded panel will take the available height to be displayed. It doesn't matter if we resize the container.
Note
In the Accordion layout, it is important to point out that we only need to use the Ext.panel.Panel
class or subclasses of the Ext.panel.Panel
class.
The Anchor layout
This layout enables the anchoring of contained elements (child elements) relative to the container's dimensions. If the parent container is resized, then the child elements will be resized according to the rules applied to these child elements.
By default, AnchorLayout
will calculate anchor measurements based on the size of the container itself. But if the container is using the AnchorLayout
property, it will supply an anchoring-specific config
property of anchorSize
. If the anchorSize
property is specified, the layout will use it as a virtual container for the purposes of calculating the anchor measurements based on it instead the container itself.
Let's make some changes to the previous examples and set the code like this:
Ext.onReady(function(){ var win = Ext.create("Ext.window.Window",{ title: "My first window", width: 300, height: 300, maximizable : true, layout: "anchor", defaults: {xtype: "panel", height: 60, border: false}, items: [ { title: "Menu", html: "panel at 100% - 10 px", anchor:'-10' },{ title: "Content", html: "panel at 70% of anchor", anchor:'70%' },{ title: "3rd Panel", html: "panel at 50% width and 40% height of anchor", anchor:'50% 40%', bodyStyle:'background-color:#fc3;' } ] }); win.show(); });
The screen will look like the following screenshot:
When we use the anchor
property with only one value, anchoring will be used on the width of the component, for example, anchor:'70%'
will cover 70% of the parent container's width. Using anchor:'-10'
will cover 100% minus 10 pixels of the parent container's width. Lastly, when using two values, the anchoring will be applied to the width and height as in the last panel from the code: anchor:'50% 40%'
.