Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Latest commit

 

History

History
123 lines (98 loc) · 3.18 KB

appendix-web-component-field-strategy.asciidoc

File metadata and controls

123 lines (98 loc) · 3.18 KB
title order layout
Appendix: Using a Web Component Field
100
page

Using a Web Component Field

While Vaadin Components are supported out-of-the-box, the client-side Form binder can be configured to support any web component. This article explains how to configure the binder for using a custom text-field web component.

Example of a Web Component

Let us consider this LitElement component for using in form binding:

Example web component field
import {LitElement, customElement, html, property} from 'lit-element';
import '@vaadin/vaadin-custom-field';
import '@vaadin/vaadin-text-field';

@customElement('my-cc-field')
export class MyTextField extends LitElement {
  @property({type: String}) label = '';
  @property({type: String}) value = '';
  @property({type: Boolean}) required = false;
  @property({type: Boolean}) invalid = false;
  @property({type: String}) errorMessage = '';

  onValueChanged(event) {
    this.value = event.target.value;
  }

  render() {
    return html`
      <vaadin-custom-field
       .label="${this.label}
       .value="${this.value}
       @value-changed="${this.onValueChanged}
       .required="${this.required}
       .invalid="${this.invalid}
       .errorMessage="${this.errorMessage}
      >
        <vaadin-text-field></vaadin-text-field>
      </vaadin-custom-field>
    `;
  }
}

Define a custom field strategy

First step towards using a web component as a field is to define a field strategy. Import and create a subclass of AbstractFieldStrategy, as in the example below:

Example field strategy
import {AbstractFieldStrategy} from '@vaadin/form';

class MyTextFieldStrategy extends AbstractFieldStrategy {
  set required(required: boolean) {
    this.element.required = required;
  }

  set invalid(invalid: boolean) {
    this.element.invalid = invalid;
  }

  set errorMessage(errorMessage: string) {
    this.element.errorMessage = errorMessage;
  }
}

Use a custom field strategy in your binder

Subclass the binder and override the getFieldStrategy(element) method to use a custom field strategy for the my-text-field component:

Using a custom field strategy in the binder
import {AbstractModel, Binder, FieldStrategy} from '@vaadin/form';

class MyBinder<T, M extends AbstractModel<T>> extends Binder<T, M> {
  constructor(context: any, model: M) {
    super(context, model);
  }

  getFieldStrategy(element: any): FieldStrategy {
    if (element.localName === 'my-text-field') {
      return new MyTextFieldStrategy(element);
    }
    return super.getFieldStrategy(element);
  }
}
Example form with a web component field
import {field} from '@vaadin/form';
import 'my-text-field';
import {MyBinder} from '../../my-binder';

import PersonModel from '../../generated/com/example/application/PersonModel';

class PersonForm extends LitElement {
  // ...

  private binder = new MyBinder(this, PersonModel);

  render() {
    return html`
      <my-text-field
       label="Full name"
       ...="${field(this.binder.model.fullName)}"
      ></my-text-field>
    `;
  }
}