Vaadin Elements - Combo Box - Using Custom Item Template

Using Custom Item Template

By default, items are displayed in the overlay as a list of plain strings. For some use cases it is not enough, especially when it is required to display a few Object keys in each item.

In order to give a custom markup for items, you can provide a custom item template in the light DOM of vaadin-combo-box.

When using object items, and item templates, it is still necesary to set the item-label-path property, because the value specified by this is displayed in the input field when the item is selected, and it’s also used for filtering.
<vaadin-combo-box
    id="elements-template-box"
    label="Element"
    item-label-path="name"
    item-value-path="symbol">
  <template>
    <b>[[item.name]], <sub>[[item.number]]</sub>[[item.symbol]]</b><br>
    array index: [[index]]
  </template>
</vaadin-combo-box>

<script>
  var elementsTemplateBox = document.querySelector('#elements-template-box');

  // elementsJson is an Array of Objects. Item object format:
  //   {name: 'Hydrogen', symbol: 'H', number: 1}
  elementsTemplateBox.items = elementsJson;
</script>
Using Custom Item Template
Figure 1. Using Custom Item Template

In the above example, the vaadin-combo-box element has the custom item template, that renders number, symbol, and name keys from the given object items.

Item Template Variables

The following properties are available for item template bindings:

Property name Type Description

index

Number

Index of the item in the items array

item

String or Object

The item reference

selected

Boolean

True when item is selected

focused

Boolean

True when item is focused

Selected and Focused Flags

You can use selected and focused flags in the item template to read the item state.

<vaadin-combo-box id="elements-selected-box" label="Element" value="Carbon">
  <template>
    <b>[[item]]</b><br>
    selected: [[selected]], focused: [[focused]]
  </template>
</vaadin-combo-box>

<script>
  var elementsSelectedBox = document.querySelector('#elements-selected-box');
  elementsSelectedBox.items = elements;
</script>
Selected and Focused Flags
Figure 2. Selected and Focused Flags

The above example shows the item states by binding to selected and focused template properties in the item text.

Styling Items with Custom Item Element

If styling the custom item template contents is necessary, you apply styles by defining a custom item element for your template and item styles.

The following example demonstrates defining a custom element. The my-item element receives the item Object property and displays the specified item keys in columns using flex layout.

my-item.html
<dom-module id="my-item">
  <template>
    <style>
      :host {
        display: flex;
      }

      span {
        flex: 1 0 100px;
        padding: 0 8px;
      }

      #symbol {
        flex: 0 0 4em;
        font-weight: bold;
      }

      #index {
        text-align: right;
      }
    </style>

    <span id="symbol">
      <sub>[[item.number]]</sub>[[item.symbol]]
    </span>
    <span>[[item.name]]</span>
    <span id="index">[[index]]</span>
  </template>

  <script>
    Polymer({
      is: 'my-item',
      properties: {index: Number, item: Object}
    });
  </script>
</dom-module>
Styling Items with Custom Item Element
Figure 3. Styling Items with Custom Item Element

Then you can use the previously defined my-item element in the item template of vaadin-combo-box:

<link rel="import" href="my-item.html">

<vaadin-combo-box id="elements-my-item-box" label="Element" item-label-path="name" item-value-path="symbol">
  <template>
    <my-item index="[[index]]" item="[[item]]"></my-item>
  </template>
</vaadin-combo-box>

<script>
  var elementsMyItemBox = document.querySelector('#elements-my-item-box');
  elementsMyItemBox.items = elementsJson;
</script>

Item Template with Material Design

The vaadin-combo-box's appearance follows Material Design guidelines. In case you want the overlay items to follow Material Design as well, you can utilize paper-item elements like in the following snippet.

If you use images in the template, make sure they have pre-defined bounds so the layout doesn’t break or jump once the images are resized after loading.
<vaadin-combo-box id="elements-paper-item" item-value-path="email" item-label-path="email">
  <template>
    <paper-icon-item style="padding: 0">
      <img src="[[item.picture.thumbnail]]" style="border-radius: 50%; width: 48px; height: 48px;" item-icon>
      <paper-item-body two-line style="min-height: 0">
        <div style="text-transform: capitalize">[[item.name.first]] [[item.name.last]]</div>
        <div secondary>[[item.email]]</div>
      </paper-item-body>
    </paper-icon-item>
  </template>
</vaadin-combo-box>
Item Template with Material Design
Figure 4. Item Template with Material Design