ComboBox: select first value?

I have seen several posts over the months and years on this subject and no one has gotten a good answer. So I’ll add my voice to the fray. :slight_smile:

I have a ComboBox. I have called comboBox.setNullSelectionAllowed(false) on it.

Next, I call comboBox.setValue(itemIds.iterator().next()) on it. I then do assert comboBox.getValue() != null, which passes.

When the UI is rendered, the combo box is blank, thus forcing the user to pick an option. This is exactly what I want to avoid.

I realize I could use a Select here, but for the time being let’s say that ComboBox is a requirement here.

How do I do this properly?

Thanks,
Laird

Now I did not probably get the question. This works perfectly well:

package com.example.cbtest;

import com.vaadin.Application;
import com.vaadin.ui.*;

@SuppressWarnings("serial")
public class CbtestApplication extends Application {
	
	ComboBox cb = new ComboBox("Select a car");
	
	@Override
	public void init() {
		Window mainWindow = new Window("Cbtest Application");
		mainWindow.addComponent(cb);
		setMainWindow(mainWindow);
		
		cb.addItem("Audi");
		cb.addItem("Smart");
		cb.addItem("Chrysler");
		cb.setNullSelectionAllowed(false);
		cb.setValue(cb.getItemIds().iterator().next());
	}
}

That is essentially the code I have, and the ComboBox item is not selected. Well, VISUALLY it is not selected.

That is, I have a statement I dump to the server.log that prints out the current selection, and indeed it is selected, but the ComboBox begins life without a visual selection in it.

If it helps, I build the ComboBox not by adding items to it, but by supplying it with a Container.

Additionally, the selection code is happening during component assembly–i.e. the panel that houses this ComboBox may not be attached to a parent yet.

Any ideas of where I should start looking for problems?

Best,
Laird

Specifically, the ComboBox is being created by a FormFieldFactory that I’m using with a Form.

Inside the FormFieldFactory, comboBox.getValue() returns the first item from the ComboBox. However, sometime between being created by the FormFieldFactory and being added to the form (or at least showing up on it) the comboBox loses its selected value.

Best,
Laird

Not exactly as I can not repeat the problem properly. Just updated the code to this:

package com.example.cbtest;

import com.vaadin.Application;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.*;

@SuppressWarnings("serial")
public class CbtestApplication extends Application {
	
	ComboBox cb = new ComboBox("Select a car");
	
	@Override
	public void init() {
		Window mainWindow = new Window("Cbtest Application");
		mainWindow.addComponent(cb);
		setMainWindow(mainWindow);
		
		IndexedContainer container = new IndexedContainer();
		
		container.addItem("Audi");
		container.addItem("Smart");
		container.addItem("Chrysler");
		
		cb.setContainerDataSource(container);
		cb.setNullSelectionAllowed(false);
		cb.setValue(cb.getItemIds().iterator().next());
	}
}

And it still works (it shows Audi in the combobox when the page is loaded).

If you could provide a code snippet where the problem is reproduced, it would help…

Sure; will do.

Here’s the code that builds the container. This happens in a FormFieldFactory. “classifiers” below is an Iterable of a home-grown Java object called a Classifier, which is simply a struct, really, that has id, code and description properties:


              // Build an IndexedContainer to hold all the Classifiers
              // in a format understandable by a ComboBox.
              final IndexedContainer ic = new IndexedContainer();              
              ic.addContainerProperty("code", String.class, null);
              ic.addContainerProperty("description", String.class, null);

              for (final Classifier classifier : classifiers) {

                if (classifier != null) {
                  final String code = classifier.getCode();
                  if (code != null) {
                    
                    final Item classifierItem = ic.addItem(classifier);
                    assert classifierItem != null;
                    
                    final Property classifierCodeProperty = classifierItem.getItemProperty("code");
                    assert classifierCodeProperty != null;
                    classifierCodeProperty.setValue(code);
                    
                    final Property classifierDescriptionProperty = classifierItem.getItemProperty("description");
                    assert classifierDescriptionProperty != null;
                    classifierDescriptionProperty.setValue(classifier.getDescription());
                    
                  }
                }

              }

              // Set up a ComboBox linked to the pile of Classifiers we just got.
              final ComboBox cb = new ComboBox(this.getCaption(pd), ic);
              cb.setItemCaptionPropertyId("description");

The form field factory then takes this ComboBox, built as you see it here, and–if it determines that the combo box is one of those that should not permit a null selection–selects the first item. So in the code below, the “field” variable is set to the ComboBox we just built above, and “required” is true:


if (required && field instanceof AbstractSelect) {
      final AbstractSelect as = (AbstractSelect)field;
      final Collection<?> itemIds = as.getItemIds();
      if (itemIds != null && !itemIds.isEmpty()) {
        final Iterator<?> i = itemIds.iterator();
        if (i != null && i.hasNext()) {
          System.out.println("*** Setting null selection allowed = false");
          as.setNullSelectionAllowed(false);
          final Object itemId = i.next();
          as.setValue(itemId);
          System.out.println("*** Selection value from field: " + as.getValue());
        }
      }
    }

The log contains the two println statements above, and the second println statement shows that indeed we have selected the first value.

I build a Form with this FormFieldFactory, and the resulting ComboBox–which contains all the proper values–does not have a default selection.

I’ll see if I can boil this down further. Thanks as always for your great product and your time on the forums.

Best,
Laird

Furthermore, I’ve confirmed that when the FormFieldFactory is invoked, the ComboBox being returned reports that it has a non-null selection in it. So something is happening after I “lose control” of the ComboBox. I’ll go look at the Form source code to see what’s going on.

The only other thing I’m doing that may be involved here is that I programmatically set focus to the first editable field in the form, and that happens to be this particular ComboBox. I’ll try moving it to see if for some reason the focus-setting code is getting in the way.

Best,
Laird

I am thinking that perhaps setPropertyDataSource() called on the field is responsible. I haven’t tested it yet.

But it looks like the call graph goes like this:

  1. Call formFieldFactory.createField()
  2. My FormFieldFactory selects the value in the ComboBox, etc.
  3. call field.setPropertyDataSource(formProperty);

I’m thinking that maybe this is deselecting the value, since, of course, the property data source is now different from what it was…?

Best,
Laird

It is hard to say without being able to test the rest of your code. Created yet another example - which also seems to work fine:

package com.example.cbtest;

import com.vaadin.Application;
import com.vaadin.data.Item;
import com.vaadin.data.Property.*;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.*;

@SuppressWarnings("serial")
public class CbtestApplication extends Application {

	Form form = new Form(new FormLayout(), new FormFieldFactory() {
		public Field createField(Item item, Object propertyId,
				Component uiContext) {

			if ("car".equals(propertyId)) {
				ComboBox cars = new ComboBox();
				cars.addItem("Audi");
				cars.addItem("Chrysler");
				cars.addItem("Smart");
				cars.setPropertyDataSource(item.getItemProperty(propertyId));
				if (cars.getValue() ==  null)
					cars.setValue(cars.getItemIds().iterator().next());
				cars.setNullSelectionAllowed(false);
				cars.setCaption("Car");
				return cars;
			} else
				return DefaultFieldFactory.get().createField(item, propertyId,
						uiContext);
		}
	});

	@Override
	public void init() {
		Window mainWindow = new Window("Cbtest Application", new SplitPanel());
		setMainWindow(mainWindow);

		// Data
		final IndexedContainer container = new IndexedContainer();
		container.addContainerProperty("speed", Integer.class, new Integer(0));
		container.addContainerProperty("car", String.class, null);
		
		Object car1 = container.addItem();
		container.getContainerProperty(car1, "speed").setValue(new Integer(100));
		Object car2 = container.addItem();
		container.getContainerProperty(car2, "speed").setValue(new Integer(70));
		container.getContainerProperty(car2, "car").setValue("Chrysler");
		
		// UI
		final Table t = new Table(null, container);
		t.setSizeFull();
		mainWindow.addComponent(t);
		t.setSelectable(true);
		t.setImmediate(true);
		t.addListener(new ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				form.setItemDataSource(container.getItem(t.getValue()));
			}
		});		
		mainWindow.addComponent(form);
		
	}
}

If you can find the problem, please report back.

Thanks; will do. I’m SURE it has to be my error, I just am somewhat baffled as to where to look.

Thanks,
Laird

Hi guys,

For reference, I’ll chime in here as well in addition to my tweets on the issue.

When binding an Item to a Form, the data from the Item is populated onto the fields in the form
after
they have been created and returned from the FieldFactory. This is probably why your Field is suddenly wiped clean of any value you set, since the Item that you bind to your form probably contains null in that property.

Another thing worth noting is that setNullSelectionAllowed() only affects the UI – you can still do setValue(null) in your code and it’ll set the value of the field to null.

Edit: Forgot to tell you how to change the default value :slight_smile:

So
set the value you want to be selected in the property of the item bound to your form
in order to have a value selected.

HTH,
/Jonatan

Thanks Jonatan, your explanation resolved same problem that I had.

Hi I have the same problem and it was driving me crazy, I’m working with vaadin 7, so I don’t know if this works with vaadin 6, but the problem was that I was creating a FieldGroup as a BeanFieldGroup and setting a bean with no values on it.

So the FieldGroup shows the values of my bean no the values that I set while I was creating the layout.

Here’s how i was creating my field group:


fieldGroup = new BeanFieldGroup<UserBean>(UserBean.class);
form = new AddUserForm(); // This is a layout with controls on it
form.setRoleItems(vm.getRoles()); // I fill the combo box
contentPanelLayout.addComponent(form);
fieldGroup.bind(form.getUserName(), "name");
fieldGroup.bind(form.getUserPassword(), "password");
fieldGroup.bind(form.getUserRePassword(), "repassword");
fieldGroup.bind(form.getEmail(), "email");
fieldGroup.bind(form.getSecret(), "secret");
fieldGroup.bind(form.getAnswer(), "answer");
fieldGroup.bind(form.getRol(), "idRol"); // this is the combo box

Here’s how I fill my combobox


/**
	 * Set's the role items that are going to be display in the combo box role so it can be
	 * selected by the user
	 * @param roles List of PlatformRole to fill the combo box roles
	 */
	public void setRoleItems(List<PlatformRole> roles) {
		for (PlatformRole platformRole : roles) {
				rol.addItem(platformRole.getId());
				rol.setItemCaption(platformRole.getId(), platformRole.getDescription());
		}
		rol.setImmediate(true);
		rol.setNullSelectionAllowed(false);
//		if (roles.size() > 0) 
//		{
//			if (rol.getValue() == null) {
//				rol.setValue(rol.getItemIds().iterator().next());
//			}
//		} // This piece of code was working OK but I remove it because it doesn't matter
	}

And here’s my problem



fieldGroup.setItemDataSource(new BeanItem<UserBean>(new UserBean()));

So I change it with this and it works now



fieldGroup.setItemDataSource(new BeanItem<UserBean>(new UserBean(0,"","","","","","",1)));

I didn’t realize that the FieldGroup set the value of the controls, so I guess it was my mistake not check the docs

How to select value from combobox when it views data from SQLContainer?

SQLContainer container=null;
        
        TableQuery tq = new TableQuery(table, Db.pool);
        try {
            container= new SQLContainer(tq);
            
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

final ComboBox cm1 = new ComboBox("Salary Config");
cm1.setContainerDataSource(container);


cm1.setValue("temp");

Probably a bit late for salinda, but if you want to get the 1st item, you first access its id from the datasource, then select it:

cm1.select(container.getIdByIndex(0));

Anyone knows how to select first item by default on Vaadin 8 and when the ComboBox gets its data from a DataProvider?

How about

combo.setValue(combo.getDataProvider().fetch(new Query<>()).findFirst().orElse(null));

Thanks Piotr, will try!