官术网_书友最值得收藏!

  • Ext JS 3.0 Cookbook
  • Jorge Ramon
  • 666字
  • 2021-04-01 13:43:49

A custom column layout

Some applications have special layout requirements that cannot be met by the native Ext JS layouts. Luckily, you can extend these layouts and add the features that you need.

As an example, this recipe explains how to build a custom layout based on the column layout's features. This custom layout will allow you to separate each of the columns with a configurable distance. For example, a sample three-column ColumnLayout layout would look like this by default:

A custom column layout

But when using this recipe's custom layout, the same sample allows for user-defined space between columns:

A custom column layout

Getting ready...

Since this layout borrows heavily from Ext.layout.ColumnLayout, I recommend that you make yourself familiar with the source code of Ext.layout.ColumnLayout located in the ColumnLayout.js file of the library's SDK.

How to do it...

  1. Create the namespace for your custom layout:
    Ext.namespace('Ext.ux.layout');
    
  2. Define your custom layout as an extension of Ext.layout.ContainerLayout:
    Ext.ux.layout.ColumnLayout=Ext.extend(Ext.layout.ContainerLayout, {...
    
  3. Define a configuration option for the separation between columns and use the native configuration options of Ext.layout.ColumnLayout:
    columnSpacing: 5,
    monitorResize: true,
    extraCls: 'x-column',
    scrollOffset: 0,
    
  4. Use the Ext.layout.ColumnLayout's onLayout() function and introduce the new behavior:
    onLayout: function(ct, target) {
    var cs=ct.items.items, len=cs.length, c, i;
    if (!ct.columnSpacing) {
    var nc=[];
    for (i=0; i < len; i++) {
    nc[i * 2]=cs[i];
    nc[i * 2 + 1] = new Ext.BoxComponent({
    autoEl: {
    tag: 'img',
    src: Ext.BLANK_IMAGE_URL,
    width:this.columnSpacing,
    border:0
    }
    });
    }
    nc.pop();
    ct.items.items=nc;
    ct.columnSpacing=this.columnSpacing;
    }
    if (!this.innerCt) {
    target.addClass('x-column-layout-ct');
    this.innerCt=target.createChild({ cls: 'x-column-inner' });
    this.innerCt.createChild({ cls: 'x-clear' });
    }
    this.renderAll(ct, this.innerCt);
    var size=Ext.isIE && target.dom !=Ext.getBody().dom ? target.getStyleSize() : target.getViewSize();
    if (size.width < 1 && size.height < 1) {
    return;
    }
    var w=size.width - target.getPadding('lr') - this.scrollOffset,
    h=size.height - target.getPadding('tb'),
    pw=w;
    this.innerCt.setWidth(w);
    for (i=0; i < len; i++) {
    c=cs[i];
    if (!c.columnWidth) {
    pw -=(c.getSize().width + c.getEl().getMargins('lr'));
    }
    }
    pw=pw < 0 ? 0 : pw;
    for (i=0; i < len; i++) {
    c=cs[i];
    if (c.columnWidth) {
    c.setSize(Math.floor(c.columnWidth * pw) - c.getEl().getMargins('lr'));
    }
    }
    }
    
  5. Add your custom layout to the list of available layouts:
    Ext.Container.LAYOUTS['ux.column']=Ext.ux.layout.ColumnLayout;
    
  6. Now, you can use the custom layout. Create some columns:
    var column1={
    title: 'Column 1',
    columnWidth: .3,
    html: 'Width=30%'
    }
    var column2={
    title: 'Column 2',
    columnWidth: .5,
    html: 'Width=50%'
    }
    var column3={
    title: 'Column 3',
    width: 200,
    html: 'Width=200px'
    }
    
  7. Add the columns to a container that uses your layout:
    Ext.onReady(function() {
    var container=new Ext.Viewport({
    layout: 'ux.column',
    defaults: {
    bodyStyle: 'padding:10px'
    },
    layoutConfig: {
    columnSpacing: 20
    },
    items: [column1, column2, column3]
    });
    });
    

In the following screenshot, you'll see the custom column layout in action:

How to do it...

How it works...

This recipe used the functionality of Ext.layout.ColumnLayout. The important differences reside in the introduction of a new property, columnSpacing, which defines the separation between columns in the layout.

The implementation of the columns separation occurs in the following code, inside the onLayout() function:

if (!ct.columnSpacing) {
var nc=[];
for (i=0; i < len; i++) {
nc[i * 2]=cs[i];
nc[i * 2 + 1] = new Ext.BoxComponent({
autoEl: {
tag: 'img',
src: Ext.BLANK_IMAGE_URL,
width:this.columnSpacing,
border:0
}
});
}
nc.pop();
ct.items.items=nc;
ct.columnSpacing=this.columnSpacing;
}

The first time that a layout operation occurs, this code creates a new columns array using the layout's original columns array as the source, but inserting a borderless image between each of the columns. Note how the width of image is set to columnSpacing, effectively creating the desired column separation. The assignment ct.columnSpacing = this.columnSpacing and the check on ct.columnSpacing are performed to make sure that the addition of the spacer images occurs only once and not every time that the onLayout() function is called.

There's more...

I chose Ext.ux.layout as the namespace name because, it's customary to put user extensions—remember that you are extending ContainerLayout—in the Ext.ux namespace.

See also...

  • The recipe, Positioning components in multiple columns (seen earlier in this chapter) illustrates how to display complex data, or have an organized and easy-to-navigate GUI using columns
  • The next recipe, A three-panel application layout with a single line of code explains how to build a reusable Ext JS component that encapsulates a three-panel layout
主站蜘蛛池模板: 青浦区| 天长市| 如皋市| 瑞金市| 攀枝花市| 福鼎市| 玉环县| 内江市| 来凤县| 舞阳县| 彰武县| 南召县| 普陀区| 峡江县| 长丰县| 宿松县| 苏尼特右旗| 望江县| 清苑县| 三河市| 灵台县| 汉阴县| 开封县| 瑞安市| 昭觉县| 博野县| 永清县| 巨鹿县| 安庆市| 武夷山市| 金乡县| 虞城县| 贡觉县| 裕民县| 奉新县| 海原县| 连南| 香港| 尼勒克县| 彰化市| 民县|