Another post on a Sencha Touch 2 feature that I initially thought was absent in the framework altogether, but was found hidden within its elaborate (and often tricky) source code.

I needed a CompositeField for Touch 2, but having a look at its api documentation, it was no-where to be found. I continued my search into Touch 2’s source files as earlier also, I have found classes/components I needed there but without a corresponding mention in the api docs.

But I was to be disappointed this time, there was no class/component similar to a CompositeField (like we have in ExtJs) in Touch 2’s source files.

As I pondered over the situation trying to figure out a solution, one thing that struck me was the Slider field (Ext.field.Slider). Sure enough, there’s no native Slider component in Html 5 specification, but Touch has a Slider field that behaves as a regular input component when used in Touch forms. So if there’s a way to render custom markup for Slider inside a field, there must be a way to render any other custom markup.

So I opened up the source for the slider field to notice this in its default config:

 

{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; } config: {
//There are many options here in Slider field source that I have removed as they were out of context

component: {
xtype: ‘slider’
}
},{/syntaxhighlighter}

Hmmm.. so Slider field is rendering a completely custom slider component into a field, I said to myself.

So this must be supported in the Field framework. The next target was the source of Ext.form.Field class (the base of all fields in Touch 2). There I noticed this part:

 

{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; } config: {
//More options here in source

/**
* @cfg {Boolean/Object} input An instance of the inner input for this field, if one
* has been defined.
* @todo
* @accessor
*/
component: null,

//More options{/syntaxhighlighter}

These were enough of hints required to create our custom CompositeField for Touch 2. And after some iterations of refinements, I came up with the following CompositeField class for Touch 2:

 

{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }Ext.define(‘Ext.ux.CompositeField’, {
extend: ‘Ext.field.Field’,
xtype: ‘ext_ux_compositefield’,

config: {
isField: false,
component: {
xtype: ‘panel’,
layout: {
type: ‘hbox’,
align: ‘middle’
},
defaults: {
margin: 10
}
}
}
});{/syntaxhighlighter}

The simplest of a custom field, which uses a panel as the component for the field with a default layout and default margins.

The rest you can see in the live example below (click here to open in new window):

 

The above example uses our custom CompositeField in 4 different configurations:

  1. Default – Regular hbox laid out items each having its own field label:

    {syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }{
    xtype: ‘ext_ux_compositefield’,
    label: ‘Regular Composite field’,
    component: {
    items: [
    {
    xtype: ‘datepickerfield’,
    label: ‘Enter date’,
    labelWidth: 100,
    placeHolder: ‘Enter date’
    },
    {
    xtype: ‘numberfield’,
    label: ‘Or enter age’,
    labelWidth: 100,
    placeHolder: ‘or age’
    }
    ]
    }
    }{/syntaxhighlighter}

  2. Default with no nested sub-labels – Regular hbox laid out items with no nested field labels:

    {syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }{
    xtype: ‘ext_ux_compositefield’,
    label: ‘Composite field with no nested sub-labels’,
    component: {
    defaults: {
    labelCls: ‘x-hidden-display’
    },
    items: [
    {
    xtype: ‘datepickerfield’,
    label: ‘Enter date’,
    labelWidth: 100,
    placeHolder: ‘Enter date’
    },
    {
    xtype: ‘numberfield’,
    label: ‘Or enter age’,
    labelWidth: 100,
    placeHolder: ‘or age’
    }
    ]
    }
    }{/syntaxhighlighter}

  3. VBox layout component with nested field labels:

    {syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }{
    xtype: ‘ext_ux_compositefield’,
    label: ‘Vertically stacked composite field’,
    component: {
    layout: {
    type: ‘vbox’,
    align: ‘top’
    },
    items: [
    {
    xtype: ‘datepickerfield’,
    label: ‘Enter date’,
    labelWidth: 100,
    placeHolder: ‘Enter date’
    },
    {
    xtype: ‘numberfield’,
    label: ‘Or enter age’,
    labelWidth: 100,
    placeHolder: ‘or age’
    }
    ]
    }
    }{/syntaxhighlighter}

  4. VBox layout component with no nested field labels:

    {syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }{
    xtype: ‘ext_ux_compositefield’,
    label: ‘Vertically stacked composite field with no nested sub-labels’,
    component: {
    layout: {
    type: ‘vbox’,
    align: ‘top’
    },
    defaults: {
    labelCls: ‘x-hidden-display’
    },
    items: [
    {
    xtype: ‘datepickerfield’,
    label: ‘Enter date’,
    labelWidth: 100,
    placeHolder: ‘Enter date’
    },
    {
    xtype: ‘numberfield’,
    label: ‘Or enter age’,
    labelWidth: 100,
    placeHolder: ‘or age’
    }
    ]
    }
    }{/syntaxhighlighter}

It was far easier in the end, than it appeared initially. Also the fact that we can render any custom component inside a Field with any layout means you can create the most complex of Form UIs with deep nesting of fields using the CompositeField approach.