Hilla Documentation

Binding Arrays

Working with arrays when building TypeScript form views using form binding.

This article explains working with arrays when building TypeScript form views using form binding.

Consider a form for a Java bean that has this structure:

/**
 * Example bean with array field
 */
public class Group {
    ...

    public Person[] getPeople() {
        ...
    }

    public void setPeople(Person[] people) {
        ...
    }
}

Repeating the Array Item Template

A common need when working with arrays is to iterate over the items and stamp a template for every item.

With form binding, array models are iterable. You can iterate over the array model directly; there is no need to get the value of the array.

When iterating over an array model, you receive a binder node for the child item, which provides the item model and value inside the loop.

We suggest using a repeat directive to loop through the items and stamp the item templates.

import { html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';

import { repeat } from 'lit/directives/repeat.js';

import { Binder, field } from '@hilla/form';

import GroupModel from '.../GroupModel';

@customElement('group-form-view')
class GroupFormView extends LitElement {
  binder = new Binder(this, GroupModel);

  render() {
    return html`
      ${repeat(this.binder.model.people, personBinder => html`
        <div>
          <vaadin-text-field
           label="Full name"
           ${field(personBinder.model.fullName)}
           ></vaadin-text-field>

          <strong>Full name:</strong>
          ${personBinder.value.fullName}
        </div>
      `)}
    `;
  }
}

Adding and Removing Array Items

To append or prepend a new item to an array, use the appendItem() method on the array binder node:

this.binder.for(this.binder.model.people).appendItem();
this.binder.for(this.binder.model.people).prependItem();

By default, the new item values are empty. You can optionally specify the new item value as an argument:

this.binder.for(this.binder.model.people).appendItem({fullName: 'Jane Doe'});

To remove an item, use the removeSelf() method on the item binder node:

personBinder.removeSelf();

The following example demonstrates adding and removing array items with the form view template:

class GroupFormView extends LitElement {
  // ...

  render() {
    return html`
      ${repeat(this.binder.model.people, personBinder => html`
        <div>
          <vaadin-text-field
           label="Full name"
           ${field(personBinder.model.fullName)}
           ></vaadin-text-field>

          <vaadin-button
           @click=${() => personBinder.removeSelf()}>
              Delete
          </vaadin-button>
        </div>
      `)}

      <vaadin-button
       @click=${() => this.binder.for(this.binder.model.people).appendItem()}
       >Add</vaadin-button>
    `;
  }
}