1. #1
    Sencha User
    Join Date
    Jul 2011
    Posts
    28
    Vote Rating
    1
    rbrecheis is on a distinguished road

      0  

    Default Unanswered: GXT combo box displays old value after loading new ListStore content

    Unanswered: GXT combo box displays old value after loading new ListStore content


    Hi,

    I have two combo boxes: one for selecting companies and one, given a selected company, for selecting employees. If you select a company, the employee combo box loads that company's employee list and should display the first item. However, in some cases the combo box still displays the old value (from the previously selected company) even though just before loading the new employee list I call setValue(null) on the combo box. I found an earlier post about combo box selection problems in GXT 3.0 mentioning you should first call setValue(null), the redraw(true) and finally setText(null). I did that and the combo box clears as it should... until the new employee list is loaded and the first employee is set with the setValue(employee) method. Then the old value re-appears again.

    If I step into the setValue() method I end up in the render() method of ComboBoxCell.java. There's a statement "FieldViewData viewData = checkViewData(context, v)". I think here's where things go wrong. The getCurrentValue() method of the viewData object still contains the old combo box value and that is what is rendered. The checkViewData() method perfoms some kind of lookup in the context object using a key "component". Apparently, the old combo box value is still registered under this key and the corresponding FieldViewData is returned.

    To circumvent this issue I call comboBox.getCell().clearViewData("component") just before I call comboBox.setValue(). Still, I would be interested to know whether this is a bug or whether I'm doing something wrong.

    Anyone have any ideas?

    Thnx,

    Ralph
    Last edited by rbrecheis; 25 Sep 2013 at 1:33 PM. Reason: Typos

  2. #2
    Ext GWT Premium Member icfantv's Avatar
    Join Date
    Sep 2011
    Location
    Superior, CO
    Posts
    411
    Vote Rating
    21
    Answers
    20
    icfantv will become famous soon enough icfantv will become famous soon enough

      0  

    Default


    The difference between getValue and getCurrentValue is one of focus and events. getCurrentValue will always return whatever is displayed, but can be null if you're entering invalid stuff. getValue won't return the selected value until focus changes.

    My suggestion would be to add a SelectionHandler to your first combo box. The newly selected item will be part of the event and you can then update the list store of the second combo box based on the selected item of the first one. See this demo for a code sample: http://www.sencha.com/examples/#ExamplePlace:combobox

    Let us know how it goes.

  3. #3
    Sencha User
    Join Date
    Jul 2011
    Posts
    28
    Vote Rating
    1
    rbrecheis is on a distinguished road

      0  

    Default


    Hi icfantv,

    Thanks for your fast reply!

    Maybe I didn't explain myself clearly but I do have a selection handler connected to the first combo box whose onSelection() triggers a reload of the second combo box. There is no problem with this. The second combo box reacts to this event and the reload is executed as it should The problem is that after the reload the second combo box keeps displaying an old value, even if I clear the value, the text AND the underlying ListStore before reloading the data.

    I know about the difference between getValue() and getCurrentValue() although I find it highly confusing and always seem to forget what's what. Still, I'm not sure this applies to my problem. I'm not calling getValue() or getCurrentValue() anywhere on the combo box. I'm just loading new ListStore contents (on the second combo box mentioned above) and calling setValue(firstItem) to show/select the first item in the new list. Before loading the new list, I clear the combobox. I see this works because there's a slight latency between clearing the combo box and retrieving the list data from the server. However, as soon as the new list arrives in the client, gets loaded and I call setValue(firstValue) then the old value of the previous list re-appears.

    I don't see how you could explain this in terms of focus or events. At least I find it very confusing...

    Anymore thoughts?

  4. #4
    Ext GWT Premium Member icfantv's Avatar
    Join Date
    Sep 2011
    Location
    Superior, CO
    Posts
    411
    Vote Rating
    21
    Answers
    20
    icfantv will become famous soon enough icfantv will become famous soon enough

      0  

    Default


    I've created a working example for you. Note that I call setValue(null) on the second combobox to clear out the value - this is in the selection handler - if I tried, I could probably think of a use case whereby having the widget remove that value is the correct behavior, but likewise with leaving it in there.
    Code:
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.editor.client.Editor.Path;
    import com.google.gwt.event.logical.shared.SelectionEvent;
    import com.google.gwt.event.logical.shared.SelectionHandler;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.sencha.gxt.cell.core.client.form.ComboBoxCell;
    import com.sencha.gxt.data.shared.LabelProvider;
    import com.sencha.gxt.data.shared.ListStore;
    import com.sencha.gxt.data.shared.ModelKeyProvider;
    import com.sencha.gxt.data.shared.PropertyAccess;
    import com.sencha.gxt.widget.core.client.ContentPanel;
    import com.sencha.gxt.widget.core.client.container.CssFloatLayoutContainer;
    import com.sencha.gxt.widget.core.client.container.CssFloatLayoutContainer.CssFloatData;
    import com.sencha.gxt.widget.core.client.form.ComboBox;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class MultipleComboBoxTest implements EntryPoint
    {
       private static final ModelOnePropertyAccess MOPA = GWT.create(ModelOnePropertyAccess.class);
       private static final ModelTwoPropertyAccess MTPA = GWT.create(ModelTwoPropertyAccess.class);
    
       private static final Map<ModelOne, List<ModelTwo>> MAP = new HashMap<ModelOne, List<ModelTwo>>(3);
    
       static
       {
          List<ModelTwo> list = new ArrayList<ModelTwo>(3);
          list.add(new ModelTwo("a"));
          list.add(new ModelTwo("b"));
          list.add(new ModelTwo("c"));
          MAP.put(new ModelOne("one"), list);
    
          list = new ArrayList<ModelTwo>(3);
          list.add(new ModelTwo("d"));
          list.add(new ModelTwo("e"));
          list.add(new ModelTwo("f"));
          MAP.put(new ModelOne("two"), list);
    
          list = new ArrayList<ModelTwo>(3);
          list.add(new ModelTwo("g"));
          list.add(new ModelTwo("h"));
          list.add(new ModelTwo("i"));
          MAP.put(new ModelOne("three"), list);
       }
    
       @Override
       public void onModuleLoad()
       {
          ListStore<ModelOne> storeOne = new ListStore<ModelOne>(MOPA.key());
          storeOne.addAll(MAP.keySet());
    
          final ListStore<ModelTwo> storeTwo = new ListStore<ModelTwo>(MTPA.key());
          final ComboBox<ModelTwo> cbt = new ComboBox<ModelTwo>(storeTwo, MTPA.value());
          cbt.setEditable(false);
          cbt.setForceSelection(true);
          cbt.setTriggerAction(ComboBoxCell.TriggerAction.ALL);
    
          ComboBox<ModelOne> cbo = new ComboBox<ModelOne>(storeOne, MOPA.value());
          cbo.setEditable(false);
          cbo.setForceSelection(true);
          cbo.setTriggerAction(ComboBoxCell.TriggerAction.ALL);
          cbo.addSelectionHandler(new SelectionHandler<ModelOne>()
          {
             @Override
             public void onSelection(SelectionEvent<ModelOne> event)
             {
                ModelOne model = event.getSelectedItem();
                List<ModelTwo> models = MAP.get(model);
                storeTwo.replaceAll(models);
                cbt.setValue(null);
             }
          });
    
          CssFloatLayoutContainer cflc = new CssFloatLayoutContainer();
          cflc.add(cbo, new CssFloatData(150));
          cflc.add(cbt, new CssFloatData(150));
    
          ContentPanel cp = new ContentPanel();
          cp.setPixelSize(500, 400);
          cp.add(cflc);
    
          RootPanel.get().add(cp);
       }
    
       interface ModelOnePropertyAccess extends PropertyAccess<ModelOne>
       {
          @Path("value")
          ModelKeyProvider<ModelOne> key();
          LabelProvider<ModelOne> value();
       }
    
       interface ModelTwoPropertyAccess extends PropertyAccess<ModelTwo>
       {
          @Path("value")
          ModelKeyProvider<ModelTwo> key();
          LabelProvider<ModelTwo> value();
       }
    
       static class ModelOne
       {
          private String value = null;
    
          public ModelOne(String value)
          {
             this.value = value;
          }
    
          public String getValue()
          {
             return this.value;
          }
    
          public void setValue(String value)
          {
             this.value = value;
          }
       }
    
       static class ModelTwo
       {
          private String value = null;
    
          public ModelTwo(String value)
          {
             this.value = value;
          }
    
          public String getValue()
          {
             return this.value;
          }
    
          public void setValue(String value)
          {
             this.value = value;
          }
       }
    }

  5. #5
    Sencha User
    Join Date
    Aug 2013
    Posts
    1
    Vote Rating
    0
    Moonrise is on a distinguished road

      0  

    Default


    I encountered the same problem.

    I have 2 combo boxes, and on the first combo box I have a SelectionHandler in which I call the focus method of the second combo box. Then I trigger the reset method (e.g. by clicking a button) on the first combo box and it doesn't work, it keeps displaying the old value.
    This only happens when the combo box to reset is editable and the value is selected by typing. Otherwise, when I select the first value by clicking, the reset works fine but the SelectEvent doesn't seem to be called because then the second combo box won't get the focus.

    I still don't understand if this is the wanted behavior.

  6. #6
    Sencha User
    Join Date
    Jul 2011
    Posts
    28
    Vote Rating
    1
    rbrecheis is on a distinguished road

      0  

    Default


    Hi icfantv,

    I'm afraid your example doesn't really help me solving my problem. I'm not sure whether it makes any difference but I'm not setting the store elements myself but use a Proxy+Loader for that. Second, your call to cbt.setValue(null) right after storeTwo.replaceAll(models) seems to be basically the same as I do, except for the fact that I set it to a non-null value, namely the first item of the list. Perhaps if you just clear it with setValue(null) it works fine but as soon as you set a non-null value and it needs to display it, then the old value re-appears as I described earlier. Unfortunately, your example stops at the setValue(null)... I would be interested to see what happens if you select the first item of the new list and try to display that.

    Well, whatever the real issue may be I'm afraid I'm running a bit out of time looking deeper into this problem. We have some software deliveries coming up and I already spent too much time on this, especially since I have a work-around. Regardless of what anyone may say though, I find this behavior highly confusing. Sure, there may be some use cases where it might be somewhat logical but that's no reason for making it the default behavior.... That's just my opinion. GXT is a great library so I don't want to complain too much but they do make things overly complicated sometimes.

    Thanks for all your help,

    Rlp

  7. #7
    Ext GWT Premium Member gdlm's Avatar
    Join Date
    Jan 2012
    Location
    Belgium
    Posts
    209
    Vote Rating
    4
    Answers
    2
    gdlm is on a distinguished road

      0  

    Default


    Thanks rbrecheis for your workaround.
    I have exactly the same situation.
    Quite unbelievable that more than a year later this issue still exists.

Thread Participants: 3

Tags for this Thread