2
votes

I have a problem when apply an Ext.ComboBox over an existing html select item, even if the existing content makes the html select about 20px (by it's content non static width is set), the Ext.ComboBox will resize to a sort of default, large, width value. There's a way to auto resize the Ext.ComboBox based on the existing items and no using the default width?

Even if I know which best tool Ext is, this issue will let my colleagues to discard Extjs.

Thanks in advance

5

5 Answers

5
votes

You can't technically make a combo "auto width" -- Ext actually converts the <select> into a regular <input> behind the scenes, and <input> elements have to have a width/size specified. However, you can trick Ext into sizing the combo based on the existing <select> which should give you the same end result. Here's an example from the Ext combo demo page, where I have modified the width config value:

var converted = new Ext.form.ComboBox({
    typeAhead: true,
    triggerAction: 'all',
    transform:'state',
    width: Ext.fly('state').getWidth(),
    forceSelection:true
});

The obvious caveat would be that if you subsequently modify the list after it's rendered, the combo will not resize itself automatically and you'd have to figure out a way to resize it yourself.

2
votes

Use this code:

Ext.ux.ResizableComboBox = Ext.extend(Ext.form.ComboBox, {
initComponent: function(){
    Ext.ux.ResizableComboBox.superclass.initComponent.call(this);
    this.on('render', this.resizeToFitContent, this);
},
resizeToFitContent: function(){
 if (!this.elMetrics){
            this.elMetrics = Ext.util.TextMetrics.createInstance(this.getEl());
 }
 var m = this.elMetrics, width = 0, el = this.el, s = this.getSize();
 this.store.each(function (r) {
            var text = r.get(this.displayField);
            width = Math.max(width, m.getWidth(text));
        }, this);
 if (el) {
            width += el.getBorderWidth('lr');
            width += el.getPadding('lr');
        }
 if (this.trigger) {
            width += this.trigger.getWidth();
 }
 s.width = width;
 this.setSize(s);
 this.store.on({
            'datachange': this.resizeToFitContent,
            'add': this.resizeToFitContent,
            'remove': this.resizeToFitContent,
            'load': this.resizeToFitContent,
            'update': this.resizeToFitContent,
            buffer: 10,
            scope: this
 });
    }
});Ext.reg('resizable-combo', Ext.ux.ResizableComboBox);
0
votes

In addition to what bmoeskau suggests, you can use an xtemplate for your combo's items. This will give you the ability to change the look of the item. You can wrap text, add images, etc.

0
votes

add a listener to the afterrender event and set the width if the list (the div that drops down ) to auto e.g.

afterrender: function(combo){                   
                combo.list.setSize('auto', 0);
                combo.innerList.setSize('auto', 0);
            }

The reason I am using afterrender and not render is because if you set lazyInit to false it will set the list width, so in afterrender you override that setWidth

-1
votes

I'm pretty sure you can get ExtJs to render whatever html items you need to, in the way you want them to be rendered.

here's some code from the Examples/Form/Combos.js file:

var converted = new Ext.form.ComboBox({
    typeAhead: true,
    triggerAction: 'all',
    transform:'state',
    width:20, //<-- set this config value!
    forceSelection:true
});

in the code that you're using to transform the combo, just specify a width for the ExtJs combo.