title | order | layout |
---|---|---|
Appendix: Using a Web Component Field |
100 |
page |
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.
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>
`;
}
}
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;
}
}
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>
`;
}
}