Array
This example demonstrates array field and array operations.
It also demonstrates the use of custom valueFormatter
and valueParser
on the unit price fields.
Key Concepts
This example demonstrates how to manage a dynamic list of fields, a common requirement for things like order forms or editable invoices.
-
Binding to Array Items: The
field()
directive can bind to a specific item in an array using dot notation with an index (e.g.,items.0.productId
). In the example, we use Lit'srepeat
directive to loop through theitems
array and generate a row for each item, using the indexidx
to create the correct binding for each field.${repeat(value.items, (_, idx) => idx, this.#itemTemplate)}
// Inside the item template html`<select-field ${form.field(`items.${idx}.productId`)}></select-field>`
-
Array Manipulation API: The
FormController
(which is aFieldGroup
) provides methods for manipulating arrays in the form's value. You call the method with the path to the array and the necessary arguments.pushItem("items", ...)
: Adds a new item to the end of theitems
array.removeItem("items", idx)
: Removes the item at the specifiedidx
.moveItem("items", idx, newIdx)
: Moves an item from one index to another.
These methods automatically update the form state, triggering a re-render of the
repeat
directive. -
Custom Formatting and Parsing: The "Unit Price" field uses a
valueFormatter
to display the number as a currency string (e.g., "$10.00") and avalueParser
to convert the string back into a number when the user changes it. This is useful for handling data that has a different representation in the UI versus the data model.<number-field .valueParser=${parseCurrency} .valueFormatter=${formatCurrency} ${form.field(`items.${idx}.unitPrice`)} ></number-field>
-
Derived State with
@lit/task
: The total price is calculated using@lit/task
. The task is configured to re-run its calculation whenever theitems
array changes, providing a clean and reactive way to display computed values.