You found a bug! We've classified it as EXTGWT-1932 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #11
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,732
    Vote Rating
    90
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    Thanks for the report, and the feedback. I wonder if you can give a little more detail on how you are using the ComboBox - if you are using it to store and filter Strings, I have another suggestion that might make sense.

    Make is a ComboBox<String>, and instead of trying to tell the ComboBox that the new string is merely not an error, give it a custom PropertyEditor<String> instead. The purpose of a PropertyEditor (the name is a holdover from 2.x, before there was such a thing as the Editor framework) is to turn the text the user enters into a value that can be used from code, and vice versa - how to print the values from model objects into text on the screen.

    The default PropertyEditor for ComboBox (actually for the ComboBoxCell) is ComboPropertyEditor - it uses the protected method T selectByValue(String) to try to figure out what value in the store matches the current string.

    If, as I said, you want to support any string value, this is a great way to add a value to the Store if it fits, or to just say 'yep, that string is a string, and strings are values' - no need to test against every value in the store.

    That said, yes, our current behavior on clearValueOnParseError=false clearly doesn't make sense, and it is quite possible that forceSelection doesn't make sense given the differences between 2.x and 3. I'm currently focusing on how we can make clearValueOnParseError work - and trying to ensure that it will be enough to satisfy the forceSelection behavior.

  2. #12
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,732
    Vote Rating
    90
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    Merging two threads to allow discussion on these two setters and how the PropertyEditor can be used.

    I'm currently of the opinion that if a non-matching value is entered, it should be drawn as an error, and clearValueOnParseError and forceSelection *only* govern what to do with regard to the old errors. ForceSelection=true would avoid the issue by selecting some value (last, or closest match), and if false, then either the string should be retained or cleared (clearValueOnParseError). If you want the value to be not only kept but made available from comboBox.getValue, then a new PropertyEditor is in order. Thoughts?

  3. #13
    Sencha User
    Join Date
    Apr 2012
    Posts
    3
    Vote Rating
    0
    Spirann is on a distinguished road

      0  

    Default Temporary workaround

    Temporary workaround


    I've temporarily found a dirty workaround:
    I've extended ComboBox and overided the onBlur method :
    Code:
        @Override
        protected void onBlur(Event be) {
            String value = getCell().getText(getElement());
            super.onBlur(be);
            setValue(value);
        }
    But I'll try the PropertyEditor today

  4. #14
    Sencha User
    Join Date
    Jan 2013
    Posts
    8
    Vote Rating
    0
    ryanshillington is on a distinguished road

      0  

    Default More robust solution

    More robust solution


    I have a slightly more robost work-around. This allows me to set new values regardless of whether my ComboBox type is a String.

    Code:
    import com.google.gwt.core.shared.GWT;
    import com.google.gwt.user.client.Event;
    import com.sencha.gxt.data.shared.Converter;
    import com.sencha.gxt.data.shared.LabelProvider;
    import com.sencha.gxt.data.shared.ListStore;
    import com.sencha.gxt.widget.core.client.form.ComboBox;
    
    
    /**
     * The purpose of this class is to fix bug EXTGWT-1932 in the GXT combo box
     */
    public class CustomComboBox<V> extends ComboBox<V> {
        protected Converter<V, String> fromStringConverter;
    
    
        public CustomComboBox(ListStore<V> store, LabelProvider<? super V> labelProvider) {
            super(store, labelProvider);
        }
    
    
        public void setFromStringConverter(Converter<V, String> fromStringConverter) {
            this.fromStringConverter = fromStringConverter;
        }
    
    
        @Override
        protected void onBlur(Event be) {
            String stringValue = getCell().getText(getElement());
            super.onBlur(be);
            if (fromStringConverter != null) {
                V value = fromStringConverter.convertFieldValue(stringValue);
                ListStore<V> store = getStore();
                if(store.findModel(value) == null)
                {
                    store.add(value);
                    store.commitChanges();
                }
                setValue(value, true);
                GWT.log("Changed value to " + value);
            }
        }
    }
    I also created a StringToStringConverter for convenience:
    Code:
    import com.sencha.gxt.data.shared.Converter;
    
    
    /**
     * The purpose of this class is to make a string a string.
     */
    public class StringToStringConverter implements Converter<String, String> {
        @Override
        public String convertFieldValue(String object) {
            return object;
        }
    
    
        @Override
        public String convertModelValue(String object) {
            return object;
        }
    }

  5. #15
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,732
    Vote Rating
    90
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    From the discussions that have taken place around this thread/issue, we are adding StringComboBox and StringComboBoxCell, which should natively support accepting the String value that the user entered. It has the option then of adding that new value to the store, or leaving it out. Additionally, there is a method to clear all user-entered values from the combo. This will be released as part of 3.0.4.

    We may remove setForceSelection from ComboBox in 3.1, as this new field will hopefully handle the cases where it makes sense to use it.

  6. #16
    Sencha User
    Join Date
    Jan 2013
    Posts
    8
    Vote Rating
    0
    ryanshillington is on a distinguished road

      0  

    Default Property Editor was the way to go

    Property Editor was the way to go


    My previous solution failed on a number of fronts. After about a day of debugging, I came across the PropertyEditor solution that Colin spelled out very clearly in comment #11 above. I should have read that closer.

    Here's the code, for idiots like me who think that comments that don't provide code don't have the solution :-).

    Code:
                comboBox.getCell().setPropertyEditor(new PropertyEditor<V>() {
                    @Override
                    public V parse(CharSequence text) throws ParseException {
                        // Convert the text to your object here (or just return text.toString() if your ComboBox is of type String)
                        return converter.convertFieldValue(text.toString()); 
                    }
    
    
                    @Override
                    public String render(V object) {
                        // Convert the object to a displayable String here (or just return object if your ComboBox is of type String)
                        return converter.convertModelValue(object);
                    }
                });
    Everybody, please ignore what I said in comment #14. onBlur was not a good way to solve this.

  7. #17
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,732
    Vote Rating
    90
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    We added StringComboBox/StringComboBoxCell in GXT 3.0.4 which solves this basic issue by overriding selectByValue to look in the options in the store, and if no option matches, to optionally track that value in the store for future use. This is essentially the same as this custom PropertyEditor, but with the option of keeping user added values around (until clearUserValues() is invoked).

    The method setForceSelection will likely be removed in 3.1 or at least moved into StringComboBox/StringComboBoxCell to avoid confusion like this in the future. Sorry for the confusion caused, and thanks for coming back to update this thread as you found resolutions.

  8. #18
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    6
    Vote Rating
    0
    aryzhov is on a distinguished road

      0  

    Default


    StringComboBox kind of degrades functionality in the case if the value is wrapped in an object. For example, consider a combo box where the value is a pair of a number and name. If the user enters a number that's not in the combo box, we will create a new value with the name "User-defined". I managed to find another workaround for ComboBox behavior in GXT 3.0.6:
    Code:
    ComboBox<E> cb = new ComboBox<E>(new ComboBoxCell<E>(ls, lp, new LabelProviderSafeHtmlRenderer<E>(lp)) {
        
        @Override
        protected E selectByValue(String text) {
            E value = super.selectByValue(text); 
            if(value == null)
                value = createValueFromText(text);
            return value;
        }
        
    } );
    cb.setForceSelection(false);
    ...
    protected abstract E createValueFromText(String s);

  9. #19
    Sencha Premium Member
    Join Date
    Nov 2013
    Location
    Boston, MA
    Posts
    22
    Vote Rating
    0
    sbusch is on a distinguished road

      0  

    Default It's now March 11, 2014

    It's now March 11, 2014


    This doesn't seem to be fixed in 3.0.6 either!