Autosizing textfield label in ExtJS
Asked Answered
C

6

6

In ExtJS, is it possible to have the label of a textfield optimally sized to fit its text in one line?

The labelWidth property doesn't have an auto setting, and leaving it out completely has same effect as specifying the default value 100, which will cause a lengthy text to break over multiple lines:

http://jsfiddle.net/Qbw7r/

I would like to have the label just as wide as it takes to contain the whole text without wrapping, and the editable field fill up the rest of the available width.

Corkage answered 13/9, 2013 at 17:6 Comment(1)
don't think it works that way. What about labelAlign:top ? That should give you plenty of room.Tune
R
5

You could also use Ext.util.TextMetrics to measure the length of your label and set the labelWidth accordingly. (See this fiddle).

var label = 'Changing text with variable length',
    tm = new Ext.util.TextMetrics(),
    n = tm.getWidth(label + ":"); //make sure we account for the field separator

Ext.create('Ext.form.Panel', {
    bodyPadding: 10,
    bodyStyle: 'background-color: #cef',
    items: [{
        xtype: 'textfield',
        emptyText: 'no data',
        fieldLabel: label,
        labelWidth: n
    }],
    margin: 25,
    renderTo: Ext.getBody()
});

If you need a more general solution, take a look at the example in the comment provided by slemmon in the ExtJS docs. Essentially, his example creates an extension of the text field which dynamically sets the label width based on the label. Here is his example:

Ext.define('MyTextfield', {
    extend: 'Ext.form.field.Text',
    xtype: 'mytextfield',
    initComponent: function () {
        var me = this,
            tm = new Ext.util.TextMetrics();

        me.labelWidth = tm.getWidth(me.fieldLabel) + 10;
        tm.destroy();

        me.callParent(arguments);
    }
});
Rambutan answered 17/9, 2013 at 0:13 Comment(3)
The solution from the docs doesn't seem to work: jsfiddle.net/Qbw7r/11 Did you actually try it? Anyway, when the labelWidth is precomputed with TextMetrics and set directly in the configuration, everything is fine. This is exactly what I was looking for.Corkage
It doesn't work because you set anchor: 100%. If you remove that, it works fine. Mind you, labelWidth doesn't seem to work at all (with or without the extension) when you specify an anchor configuration on the field.Rambutan
Couldn't use because Sencha Architect doesn't take well to defining initComponent, so I listen to "added" event and in that handler do textMetrics = new Ext.util.TextMetrics(); component.labelWidth = textMetrics.getWidth (component.fieldLabel + component.labelSeparator) + component.labelPad; textMetrics.destroy();Ridgway
P
5

It worked for me like that:

 labelWidth: 300

http://jsfiddle.net/Qbw7r/7/

OR to make autosize, You could try it like that:

//  anchor: '100%',
    labelStyle: 'white-space: nowrap;'

http://jsfiddle.net/Qbw7r/8/

Particularize answered 13/9, 2013 at 20:41 Comment(1)
I like the nowrap solutionCorkage
R
5

You could also use Ext.util.TextMetrics to measure the length of your label and set the labelWidth accordingly. (See this fiddle).

var label = 'Changing text with variable length',
    tm = new Ext.util.TextMetrics(),
    n = tm.getWidth(label + ":"); //make sure we account for the field separator

Ext.create('Ext.form.Panel', {
    bodyPadding: 10,
    bodyStyle: 'background-color: #cef',
    items: [{
        xtype: 'textfield',
        emptyText: 'no data',
        fieldLabel: label,
        labelWidth: n
    }],
    margin: 25,
    renderTo: Ext.getBody()
});

If you need a more general solution, take a look at the example in the comment provided by slemmon in the ExtJS docs. Essentially, his example creates an extension of the text field which dynamically sets the label width based on the label. Here is his example:

Ext.define('MyTextfield', {
    extend: 'Ext.form.field.Text',
    xtype: 'mytextfield',
    initComponent: function () {
        var me = this,
            tm = new Ext.util.TextMetrics();

        me.labelWidth = tm.getWidth(me.fieldLabel) + 10;
        tm.destroy();

        me.callParent(arguments);
    }
});
Rambutan answered 17/9, 2013 at 0:13 Comment(3)
The solution from the docs doesn't seem to work: jsfiddle.net/Qbw7r/11 Did you actually try it? Anyway, when the labelWidth is precomputed with TextMetrics and set directly in the configuration, everything is fine. This is exactly what I was looking for.Corkage
It doesn't work because you set anchor: 100%. If you remove that, it works fine. Mind you, labelWidth doesn't seem to work at all (with or without the extension) when you specify an anchor configuration on the field.Rambutan
Couldn't use because Sencha Architect doesn't take well to defining initComponent, so I listen to "added" event and in that handler do textMetrics = new Ext.util.TextMetrics(); component.labelWidth = textMetrics.getWidth (component.fieldLabel + component.labelSeparator) + component.labelPad; textMetrics.destroy();Ridgway
B
1

what I have done was to disable the fieldLabel for the textField and add a Ext.form.Label in front of the textField. Ext.form.Label has the shrinkWrap config. I hope this helps and if you figured other workarounds that does not imply modifying the default functionality of the components please let me know :). I should say that I am using Sencha Architect and that's why I would like to add custom scripts as little as possible.

Blackmore answered 10/12, 2014 at 13:53 Comment(1)
Thanks. After trying to do what you say the components don't show up in the same line: jsfiddle.net/swvqaoj6. I guess I must be missing something.Corkage
L
1

You can actually set the label width as auto. Try this:

labelWidth: false,
labelStyle: 'width: auto'
Lambency answered 19/10, 2017 at 16:53 Comment(0)
C
0

One simple solution that could be helpful all over your app is to override the 'onRender' event. Using Ext.util.TextMetrics to calculate the text width:

(Here is an example on radiogroup)

Ext.define('NG.override.form.field.Radio', {
    override: 'Ext.form.field.Radio',
    autoBoxLabelWidth: false,

    onRender: function () {
        var me = this,
            boxlabelWidth;

        me.callParent(arguments);
        me.renderActiveError();

        if (me.autoBoxLabelWidth) {
            me.tm = new Ext.util.TextMetrics(me.getEl());
            boxlabelWidth = me.tm.getWidth(me.boxLabel) + Ext.Number.from(me.autoBoxLabelWidth, 0);
            me.setWidth(boxlabelWidth);
        }
    }
});

Then set the property 'autoBoxLabelWidth' to 'true' or number of px to add:

xtype: 'radiogroup',
fieldLabel: 'Two Columns',
columns: 2,
vertical: true,
items: [{
          boxLabel: 'Item 1',
          name: 'rb',
          autoBoxLabelWidth: true,
          inputValue: '1'
        }, {
          boxLabel: 'Item 2',
          name: 'rb',
          autoBoxLabelWidth: 15,
          inputValue: '2',
          checked: true
        }]
Collaborationist answered 28/5, 2017 at 13:18 Comment(0)
C
0

You can also try

width: '100%'
Cheloid answered 20/10, 2017 at 17:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.