How do I create a non-editable GXT ComboBox?
Asked Answered
I

4

5

I'm using GWT/GXT and trying to create a "normal" ComboBox - one that you cannot type in, but you can type a single character and it will automatically go to the first item in the list that starts with that letter. So, I don't want it READONLY, I want it so that you cannot replace the text in it with your own text (can't type characters into it).

I cannot figure out how to get ComboBox or SimpleComboBox to do this. I've tried every combination of settings on it to no avail. I did see there is a GXT ListBox, but i need a component that extends from Field.

Is there really no way to do this or am I missing something?

Idyll answered 25/3, 2010 at 18:0 Comment(0)
I
2

ListBox does what I was looking for - it's non-editable and you can press a key while it's focused and it will go to the next match.

Idyll answered 3/10, 2012 at 14:38 Comment(0)
T
5

By using setEditable(false) and setForceSelection(true) and extending the class, you can accomplish this yourself (by watching for key presses on the widget).

First, the subclass:

package net.binarymuse.gwt.gxt.client;

import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.KeyListener;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;

public class MySimpleComboBox<T extends String> extends SimpleComboBox<T> {

    public MySimpleComboBox() {
        super();
        this.addKeyListener(new KeyListener(){
            @Override
            public void componentKeyDown(ComponentEvent event)
            {
                // Get a reference to the combobox in question
                MySimpleComboBox<T> combo = MySimpleComboBox.this;

                // Get the character that has been pressed
                String sChar = String.valueOf((char) event.getKeyCode());
                // TODO - add some checking here to make sure the character is
                //        one we actually want to process

                // Make sure we have items in the store to iterate
                int numItems = combo.getStore().getCount();
                if(numItems == 0)
                    return;

                // Check each item in the store to see if it starts with our character
                for(int i = 0; i < numItems; i++)
                {
                    String value = combo.getStore().getAt(i).getValue();
                    // If it does, select it and return
                    if(value.startsWith(sChar) || value.startsWith(sChar.toUpperCase()))
                    {
                        MySimpleComboBox.this.setSimpleValue((T) value);
                        return;
                    }
                }
            }
        });
    }

}

And the test:

package net.binarymuse.gwt.gxt.client;

import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;


public class GxtSandbox implements EntryPoint {

    public void onModuleLoad() {
        SimpleComboBox<String> box = new MySimpleComboBox<String>();
        box.add("One");
        box.add("Two");
        box.add("Three");
        box.setEditable(false);
        box.setForceSelection(true);

        RootPanel.get().add(box);
    }
}

Giving the combo box focus and pressing "T" should select "Two" in the list.

As is, the class always selects the first item in the list that starts with the character; however, it would not be difficult to modify it to make it select the next item in the list (as is typical with "real" combo boxes).

Tearful answered 28/3, 2010 at 23:38 Comment(3)
I guess i wasn't clear. I know I can do it all myself, I just assumed there must be a built-in way to do this with the proper options. Maybe there isn't?Idyll
I don't see one that makes sense. The options that "you'd think" would invoke this behavior, don't. Perhaps it's a bug, or a good feature request.Tearful
Yeah - that's what I figured but I was hoping I had just missed something. Thanks.Idyll
B
5

Old post but this is very frustrating, I agree. The below is probably what you're looking for.

SimpleComboBox<String> names = new SimpleComboBox<String>();
names.add( "Brian" );
names.add( "Kevin" );
names.add( "Katie" );
names.setTriggerAction( TriggerAction.ALL );
Brutalize answered 17/8, 2012 at 23:46 Comment(0)
I
2

ListBox does what I was looking for - it's non-editable and you can press a key while it's focused and it will go to the next match.

Idyll answered 3/10, 2012 at 14:38 Comment(0)
T
2

Using ListBox is good, but it is gwt, not gxt (At least for gxt 2.2.5 there is not ListBox). For such situations when you have to use gxt api cosider following code (it works, i have tested):

SimpleComboBox<MyEmumType> simpleComboBox = new SimpleComboBox<MyEmumType>();
List<MyEmumType> values = Arrays.asList(MyEmumType.values());
//here you set all values
simpleComboBox.add(values);
//here set first to display. it does not add new, just display one from collection
simpleComboBox.setSimpleValue(values.iterator().next());
//prevent combobox for setting/searching values out of collection
simpleComboBox.setEditable(false);
//disable autocomplete, with first value it will display all others
simpleComboBox.setTriggerAction(ComboBox.TriggerAction.ALL);

P.S. I have use a enum here, but think that code works with other types.

Thielen answered 6/12, 2015 at 6:18 Comment(2)
I stated "I''m using GWT/GXT and trying to create a "normal" ComboBox", so a GWT solution is acceptable (though the question does indicate I was looking for a GXT solution, but that really wasn't a requirement). Your solution looks good though.Idyll
Thanks! I was looking for a GXT (non-GWT) solution, and setEditable(false) and setTriggerAction(TriggerAction.ALL) works great. +1Sloth

© 2022 - 2024 — McMap. All rights reserved.