Learning Ext JS(Fourth Edition)
上QQ阅读APP看书,第一时间看更新

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:

The Fit layout

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:

The Accordion layout

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:

The Anchor layout

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%'.