PDA

View Full Version : Calling setValue on a ComboBox does nothing



dcahalane
13 Nov 2009, 9:51 AM
How do you programatically select items in a ComboBox? I've got a ComboBox added to a FormPanel. After the component has been added to the form, I need to set its value to something returned from a call to the server. I've added a StoreListener where I call its setValue, but the item is never selected.

reportStore.addStoreListener(new StoreListener() {
@SuppressWarnings("unchecked")
public void handleEvent(BaseEvent e) {
Number defRepId = (Number)user.get(User.DEFAULT_REP_ID_FK_PROPERTY);
if(defRepId != null){
for(Report r : cboReport.getStore().getModels()){
Integer repId = (Integer)r.get(Report.REP_ID_PROPERTY);
if(defRepId.equals(repId)){
cboReport.setValue(r);

break;
}
}
}
}
});

I've also tried the cboReport.setSelection(selection) and select(r), neither seemed to do anything.

sven
13 Nov 2009, 10:02 AM
Which version of GXT are you using? I tested it aginst the latest one without any problems.

dcahalane
13 Nov 2009, 10:07 AM
2.0.1. using Eclipse. The only thing I can think of is that my storelistener is being fired after its been displayed?(after the containers onRender is called.)

sven
13 Nov 2009, 10:08 AM
You should try to post afully working example that implements entrypoint and demonstrates exactly what you are doing.

dcahalane
13 Nov 2009, 11:29 AM
Great suggestion. Building the small test case isolated the problem, which is that when I use any type of field binding, it resets the combobox value to null. (The combobox isnt bound to anything. If you comment out the line binding.bind(report); everything works fine. I'd say that's a bug.


public class Report extends BaseModel{
public static final String NAME_PROPERTY = "name";
public static final String REP_ID_PROPERTY = "repId";
}

public class TestPanel extends LayoutContainer{
FormBinding binding;
Report report = new Report();

public TestPanel(){
super();
setLayout(new FlowLayout(0));
}
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
ContentPanel panel = new ContentPanel();
panel.setHeading("User Information");
panel.setBodyBorder(false);
panel.setLayout(new FitLayout());
panel.setSize(825, 500);
panel.add(createMainForm());
add(panel);
}
Integer defRepId = 2;
ComboBox<Report> cboReport;
private FormPanel createMainForm() {
FormPanel retVal = new FormPanel();
retVal.setHeaderVisible(false);
TextField<String> firstName = new TextField<String>();
firstName.setFieldLabel("Name");
firstName.setMaxLength(20);
firstName.setAllowBlank(false);
retVal.add(firstName);

cboReport = new ComboBox<Report>();
cboReport.setDisplayField("name");
cboReport.setFieldLabel("Report");
cboReport.setForceSelection(true);
cboReport.setTriggerAction(TriggerAction.ALL);
cboReport.addListener(Events.SelectionChange, new Listener(){
public void handleEvent(BaseEvent be) {
List selected = cboReport.getSelection();
if(selected != null && selected.size() > 0){
Object o = selected.get(0);
}
}
});
ListStore<Report> reportStore = new ListStore<Report>();
cboReport.setStore(reportStore);
reportStore.addStoreListener(new StoreListener() {
@SuppressWarnings("unchecked")
public void handleEvent(BaseEvent e) {
for(Report r : cboReport.getStore().getModels()){
Integer repId = (Integer)r.get(Report.REP_ID_PROPERTY);
if(defRepId.equals(repId)){
cboReport.setValue(r);

break;
}
}
}
});
List<Report> reportList = new ArrayList<Report>();
reportStore.add(reportList);
retVal.add(cboReport);
Button testBtn = new Button("Test");
retVal.add(testBtn);
testBtn.addListener(Events.Select, new Listener(){
@Override
public void handleEvent(BaseEvent be) {
report.set(Report.NAME_PROPERTY, "Report Name");
binding.bind(report);
List<Report> reportList = new ArrayList<Report>();
for(int i=0; i<5;i++){
Report r = new Report();
r.set(Report.REP_ID_PROPERTY, new Integer(i));
r.set(Report.NAME_PROPERTY, "Report " + i);
reportList.add(r);
}
cboReport.getStore().removeAll();
cboReport.getStore().add(reportList);

}

});
binding = new FormBinding(retVal);
binding.addFieldBinding(new FieldBinding(firstName, Report.NAME_PROPERTY));
binding.bind(report);//REMOVE TO MAKE COMBOBOX setValue WORK.
return retVal;
}
}



/**
* This is the entry point method.
*/
public void onModuleLoad() {
Viewport viewport = new Viewport();
viewport.setLayout(new FitLayout());


final TestPanel report = new TestPanel();

viewport.add(report);



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

sven
13 Nov 2009, 11:40 AM
Before calling something a bug, you should have debugged that code. It is not a bug. You need to eb very carefully before calling something a bug.


Binding is done deferred. Also i suggest to rethink your hole logic. I dont see a point for your storelistener.

dcahalane
13 Nov 2009, 11:49 AM
Since the binder has not been attached to this component, why would calling its bind method have any impact on the ComboBox? It shouldn't, therefor a "Bug". The deferred nature of binding isn't in question. If I was binding the ComboBox and also using a StoreListener, then I would agree that it wasn't a bug. It was acting as it should due to its deferred design. However, since the ComboBox was not bound at all, the bind method should never have been called. (I never call binding.autoBind(); so I cant see why the ComboBox would be impacted by the form binding at all)
The reason I have a StoreListener and am not binding the component, is that the items that will be persisted are not the same as are contained within the combobox. Since I am not able to use normal binding, I have a Selection Listener on the component and the StoreListener to effectively handle the binding. (Yes, I know I can use a converter, but I gave up trying to use those as they are a bit less intuitive to use. (I didn't want to say "buggy", that would be an overstatement on my part)

sven
13 Nov 2009, 11:58 AM
Fixed in SVN. Formatting and documenting the code would help next time. ComboBox also was not bound. The problem was that FormBinding cleared the hole FormPanel on unbind. I changed it to only clear the bound fields.