> Markdown version of [Combo Box](https://vaadin.com/docs/v14/ds/components/combo-box). Section index: [llms.txt](https://vaadin.com/docs/v14/ds/llms.txt)

# Combo Box

Combo Box allows the user to choose a value from a filterable list of options presented in an overlay. It supports lazy loading and can be configured to accept custom typed values.

`ComboBoxBasic.java`

```java
ComboBox<Country> comboBox = new ComboBox<>("Country");
comboBox.setItems(DataService.getCountries());
comboBox.setItemLabelGenerator(Country::getName);
add(comboBox);
```

`Country.java`

```java
public class Country {

  private String name;

  private String abbreviation;

  private Integer id;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getAbbreviation() {
    return abbreviation;
  }

  public void setAbbreviation(String abbreviation) {
    this.abbreviation = abbreviation;
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  @Override
  public int hashCode() {
    return id;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof Country)) {
      return false;
    }
    Country other = (Country) obj;
    return id == other.id;
  }
}
```

The overlay opens when the user clicks the field using a pointing device. Using the Up/Down arrow keys or typing a character (found in at least one of the options) when the field is focused also opens the popup.

## <a id="common-input-field-features"></a>Common Input Field Features

Combo Box includes all Text Field and shared input field features.

- [See Text Field features](https://vaadin.com/docs/v14/ds/components/text-field.md)

- [See shared input field features](https://vaadin.com/docs/v14/ds/components/input-fields.md)

## <a id="custom-value-entry"></a>Custom Value Entry

Combo Box can be configured to allow entering custom values that are not included in the list of options.

`ComboBoxCustomEntry1.java`

```java
ComboBox<String> comboBox = new ComboBox<>("Browser");
comboBox.setAllowCustomValue(true);
add(comboBox);
```

Allowing custom entry is useful when you need to present the most common choices but still give users the freedom to enter their own options.

Custom values can also be stored and added to the list of options:

`ComboBoxCustomEntry2.java`

```java
ComboBox<String> comboBox = new ComboBox<>("Browser");
comboBox.setAllowCustomValue(true);
comboBox.addCustomValueSetListener(e -> {
  String customValue = e.getDetail();
  if (items.contains(customValue)) return;
  items.add(customValue);
  comboBox.setItems(items);
  comboBox.setValue(customValue);
});
add(comboBox);
```

## <a id="custom-item-presentation"></a>Custom Item Presentation

See [Select, Custom Item Presentation.](https://vaadin.com/docs/v14/ds/components/select.md#custom-item-presentation)

Items can be customised to display more information than a single line of text.

`ComboBoxPresentation.java`

```java
ComboBox<Person> comboBox = new ComboBox<>("Choose doctor");
comboBox.setItems(filter, DataService.getPeople());
comboBox.setItemLabelGenerator(person -> person.getFirstName() + " " + person.getLastName());
comboBox.setRenderer(getRenderer());
comboBox.getStyle().set("--vaadin-combo-box-overlay-width", "16em");
add(comboBox);

...

// NOTE
// We are using inline styles here to keep the example simple.
// We recommend placing CSS in a separate style sheet and to
// encapsulating the styling in a new component.

private TemplateRenderer<Person> getRenderer() {
  StringBuilder tpl = new StringBuilder();
  tpl.append("<div style=\"display: flex;\">");
  tpl.append("  <img style=\"height: var(--lumo-size-m); margin-right: var(--lumo-space-s);\" src=\"[[item.pictureUrl]]\" alt=\"Portrait of [[item.firstName]] [[item.lastName]]\" />");
  tpl.append("  <div>");
  tpl.append("    [[item.firstName]] [[item.lastName]]");
  tpl.append("    <div style=\"font-size: var(--lumo-font-size-s); color: var(--lumo-secondary-text-color);\">[[item.profession]]</div>");
  tpl.append("  </div>");
  tpl.append("</div>");

  return TemplateRenderer.<Person>of(tpl.toString()).withProperty("pictureUrl", Person::getPictureUrl)
          .withProperty("firstName", Person::getFirstName).withProperty("lastName", Person::getLastName)
          .withProperty("profession", Person::getProfession);
}
```

`Person.java`

```java
public class Person {

  private String firstName;

  private String lastName;

  private String email;

  private Date birthday;

  private Integer id;

  private boolean subscriber;

  private String membership;

  private String pictureUrl;

  private String profession;

  private Address address;

  private Integer managerId;

  private boolean manager;

  private String status;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getFullName() {
    return firstName + " " + lastName;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public Date getBirthday() {
    return birthday;
  }

  public void setBirthday(Date birthday) {
    this.birthday = birthday;
  }

  public boolean isSubscriber() {
    return subscriber;
  }

  public void setSubscriber(boolean subscriber) {
    this.subscriber = subscriber;
  }

  public String getMembership() {
    return membership;
  }

  public void setMembership(String membership) {
    this.membership = membership;
  }

  public String getPictureUrl() {
    return pictureUrl;
  }

  public void setPictureUrl(String pictureUrl) {
    this.pictureUrl = pictureUrl;
  }

  public String getProfession() {
    return profession;
  }

  public void setProfession(String profession) {
    this.profession = profession;
  }

  public Address getAddress() {
    return address;
  }

  public void setAddress(Address address) {
    this.address = address;
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  @Override
  public int hashCode() {
    return id;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof Person)) {
      return false;
    }
    Person other = (Person) obj;
    return id == other.id;
  }

  public Integer getManagerId() {
    return managerId;
  }

  public void setManagerId(Integer managerId) {
    this.managerId = managerId;
  }

  public boolean isManager() {
    return manager;
  }

  public void setManager(boolean manager) {
    this.manager = manager;
  }

  public String getStatus() {
    return status;
  }

  public void setStatus(String status) {
    this.status = status;
  }
}
```

Use a custom filter to allow the user to search by the rendered properties. It is recommended to make filtering case insensitive.

## <a id="auto-open"></a>Auto Open

The overlay opens automatically when the field is focused using a pointer (mouse or touch), or when the user types in the field. You can disable that to only open the overlay when the toggle button or Up/Down arrow keys are pressed.

`ComboBoxAutoOpen.java`

```java
ComboBox<Country> comboBox = new ComboBox<>("Country");
comboBox.setAutoOpen(false);
add(comboBox);
```

`Country.java`

```java
public class Country {

  private String name;

  private String abbreviation;

  private Integer id;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getAbbreviation() {
    return abbreviation;
  }

  public void setAbbreviation(String abbreviation) {
    this.abbreviation = abbreviation;
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  @Override
  public int hashCode() {
    return id;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof Country)) {
      return false;
    }
    Country other = (Country) obj;
    return id == other.id;
  }
}
```

## <a id="popup-width"></a>Popup Width

The width of the popup is, by default, the same width as the input field. The popup width can be overridden to any fixed width in cases where the default width is too narrow.

`ComboBoxPopupWidth.java`

```java
ComboBox<Person> comboBox = new ComboBox<>("Employee");
comboBox.getStyle().set("--vaadin-combo-box-overlay-width", "350px");
add(comboBox);
```

`Person.java`

```java
public class Person {

  private String firstName;

  private String lastName;

  private String email;

  private Date birthday;

  private Integer id;

  private boolean subscriber;

  private String membership;

  private String pictureUrl;

  private String profession;

  private Address address;

  private Integer managerId;

  private boolean manager;

  private String status;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getFullName() {
    return firstName + " " + lastName;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public Date getBirthday() {
    return birthday;
  }

  public void setBirthday(Date birthday) {
    this.birthday = birthday;
  }

  public boolean isSubscriber() {
    return subscriber;
  }

  public void setSubscriber(boolean subscriber) {
    this.subscriber = subscriber;
  }

  public String getMembership() {
    return membership;
  }

  public void setMembership(String membership) {
    this.membership = membership;
  }

  public String getPictureUrl() {
    return pictureUrl;
  }

  public void setPictureUrl(String pictureUrl) {
    this.pictureUrl = pictureUrl;
  }

  public String getProfession() {
    return profession;
  }

  public void setProfession(String profession) {
    this.profession = profession;
  }

  public Address getAddress() {
    return address;
  }

  public void setAddress(Address address) {
    this.address = address;
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  @Override
  public int hashCode() {
    return id;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof Person)) {
      return false;
    }
    Person other = (Person) obj;
    return id == other.id;
  }

  public Integer getManagerId() {
    return managerId;
  }

  public void setManagerId(Integer managerId) {
    this.managerId = managerId;
  }

  public boolean isManager() {
    return manager;
  }

  public void setManager(boolean manager) {
    this.manager = manager;
  }

  public String getStatus() {
    return status;
  }

  public void setStatus(String status) {
    this.status = status;
  }
}
```

## <a id="placeholder"></a>Placeholder

Use the placeholder feature to provide an inline text prompt for the field. Do not create, or use, a separate item for this purpose.

`ComboBoxPlaceholder.java`

```java
ComboBox<Person> comboBox = new ComboBox<>("Employee");
comboBox.setPlaceholder("Select employee");
add(comboBox);
```

## <a id="custom-filtering"></a>Custom Filtering

Combo Box’s filtering, by default, is configured to only show items that contain the entered value:

`combo-box-filtering-1.ts`

```html
import { html, LitElement, customElement, state } from 'lit-element';
import '@vaadin/vaadin-combo-box/vaadin-combo-box';
import { applyTheme } from 'Frontend/generated/theme';
import countries from '../../../../src/main/resources/data/countries.json';

interface Country {
  readonly name: string;
  readonly abbreviation: string;
  readonly id: string;
}

@customElement('combo-box-filtering-1')
export class Example extends LitElement {
  constructor() {
    super();
    // Apply custom theme (only supported if your app uses one)
    applyTheme(this.shadowRoot);
  }

  @state()
  private items: Country[] = countries;

  render() {
    return html`
      <!-- tag::snippet[] -->
      <vaadin-combo-box
        label="Country"
        item-label-path="name"
        item-value-path="id"
        .items="${this.items}"
      ></vaadin-combo-box>
      <!-- end::snippet[] -->
    `;
  }
}
```

Custom filtering is also possible. For example, if we only want to show items that start with the user’s input:

`ComboBoxFiltering2.java`

```java
ComboBox<Country> comboBox = new ComboBox<>("Country");

ItemFilter<Country> filter = (country, filterString) -> country.getName().toLowerCase().startsWith(filterString.toLowerCase());
comboBox.setItems(filter, DataService.getCountries());

add(comboBox);
```

## <a id="usage-as-autocomplete-field"></a>Usage as Autocomplete Field

As the user is typing, the Combo Box will filter out the options that don’t match. Once the correct value has been found, the user can use the Up/Down arrow keys to navigate the list and the Enter key to set the value, essentially using the Combo Box as an autocomplete field.

## <a id="best-practices"></a>Best Practices

Combo Box supports lazy loading for large datasets. It reduces the initial load time, consumes less bandwidth and resources.

> **Note: Do not use as a menu**
>
> Combo Box is an input field component, not a generic menu component. Use the Menu Bar component to create overlays for actions.

## <a id="related-components"></a>Related Components

| Component                                                                 | Usage recommendations                                                                     |
| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| [Select](https://vaadin.com/docs/v14/ds/components/select.md)             | Simpler overlay selection field without filtering, lazy loading or custom value entry.    |
| [Radio Button](https://vaadin.com/docs/v14/ds/components/radio-button.md) | Better accessibility than Combo Box, as all options are visible without user interaction. |
| [List Box](https://vaadin.com/docs/v14/ds/components/list-box.md)         | Scrollable inline list of options. Supports single and multi-select.                      |
| [Menu Bar](https://vaadin.com/docs/v14/ds/components/menu-bar.md)         | Overlay menus for items that trigger actions.                                             |

`475FE91A-59C1-46FC-908E-388948F6E114`
