Binding Arrays
Working with arrays using form binding API.
This page 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 each item. With form binding, array models are iterable. You can use the useFormArrayPart
hook to iterate over the model and to get and set the value of the array.
As you also need to get the field
function for each item using the useFormPart
hook, you need to create a component for the array item template.
import { useForm, useFormArrayPart, useFormPart } from '@vaadin/hilla-react-form';
import { NumberField } from '@vaadin/react-components';
import { TextField } from "@vaadin/react-components/TextField.js";
import GroupModel from '.../GroupModel';
import PersonModel from '.../PersonModel';
function PersonForm({ model }: { model: PersonModel }) {
const { field } = useFormPart(model);
return (
<div>
<TextField {...field(model.fullName)} />
<NumberField {...field(model.age)} />
</div>
);
}
export default function GroupFormView() {
const { field, model } = useForm(GroupModel);
const { items} = useFormArrayPart(model.people);
return (
<>
<TextField {...field(model.name)} />
{items.map((person, index) => (
<PersonForm key={index} model={person} />
))}
</>
);
}
Adding & Removing Array Items
You can modify the array value by using the value
and setValue
functions provided by useFormArrayPart
.
import { useForm, useFormArrayPart, useFormPart } from '@vaadin/hilla-react-form';
import { Button, NumberField } from '@vaadin/react-components';
import { TextField } from "@vaadin/react-components/TextField.js";
import GroupModel from '.../GroupModel';
import PersonModel from '.../PersonModel';
function PersonForm({ model, remove }: { model: PersonModel, remove: () => void }) {
const { field } = useFormPart(model);
return (
<div>
<TextField {...field(model.fullName)} />
<NumberField {...field(model.age)} />
<Button onClick={remove}>Remove</Button>
</div>
);
}
export default function GroupFormView() {
const { field, model } = useForm(GroupModel);
const { items, value, setValue } = useFormArrayPart(model.people);
return (
<>
<TextField {...field(model.name)} />
{items.map((person, index) => (
<PersonForm key={index} model={person} remove={() => setValue(value!.filter((_, i) => i !== index))} />
))}
<Button onClick={() => setValue([...(value ?? []), PersonModel.createEmptyValue()])}>Add person</Button>
</>
);
}