Repeater
import { Repeater } from 'cx/widgets'; Copied Repeater renders its children for each record in a collection. Use recordAlias to specify an accessor for accessing record data within the repeater.
Example
<div class="flex flex-col gap-4" controller={PageController}>
<div class="flex flex-col gap-2">
<Repeater records={m.items} recordAlias={m.$record}>
<div class="flex items-center gap-2">
<Checkbox value={m.$record.checked} text={m.$record.text} />
<Button
icon="close"
mod="hollow"
onClick={(e, { store }) => {
store.delete(m.$record)
}}
/>
</div>
</Repeater>
</div>
<div class="flex items-center gap-4">
<div class="text-sm text-muted-foreground">
Completed:{" "}
<span
text={expr(
m.items,
(items: Item[]) => items.filter((a) => a.checked).length,
)}
/>{" "}
of <span text={m.items.length} /> tasks
</div>
<Button
onClick={(e, ins) => {
ins.getControllerByType(PageController).reset()
}}
>
Reset
</Button>
</div>
</div> Completed: 1 of 3 tasks
Typed Model
Add $record to your model interface to get type-safe access to record data:
interface PageModel {
items: Item[];
$record: Item;
}
const m = createModel<PageModel>();
Then use recordAlias={m.$record} to bind the record accessor:
<Repeater records={m.items} recordAlias={m.$record}>
<Checkbox value={m.$record.checked} text={m.$record.text} />
</Repeater>
Accessing the Record Store
Event handlers like onClick receive an instance object as the second argument. This instance contains a store that provides access to the record-specific data view. Use this to manipulate individual records:
<Button
onClick={(e, { store }) => {
store.delete(m.$record);
}}
/>
The store.delete(m.$record) call removes the current record from the parent array.
Sorting and Filtering
Use sortField and sortDirection for sorting. For filtering, use filterParams with onCreateFilter:
<div class="flex flex-col gap-4" controller={PageController}>
<TextField value={m.search} placeholder="Filter by name..." />
<Repeater
records={m.products}
recordAlias={m.$record}
sortField="name"
sortDirection="ASC"
filterParams={{ search: m.search }}
onCreateFilter={(params) => {
let predicate = getSearchQueryPredicate(params.search)
return (item: Product) => predicate(item.name)
}}
>
<div class="text-sm">
<HighlightedSearchText text={m.$record.name} query={m.search} />
<span text={expr(m.$record.price, (price) => ` - $${price}`)} />
</div>
</Repeater>
</div> Apple - $0.9
Banana - $1.2
Grapes - $2.8
Mango - $2.3
Orange - $1.5
Pineapple - $3.5
Strawberry - $4
Watermelon - $5
Nested Repeaters
For nested repeaters, define separate record aliases in your model:
<div class="flex flex-col gap-4" controller={PageController}>
<Repeater records={m.accounts} recordAlias={m.$account}>
<div class="border rounded p-3">
<div class="font-medium mb-2 leading-none" text={m.$account.name} />
<Repeater records={m.$account.transactions} recordAlias={m.$transaction}>
<div class="flex justify-between text-sm py-1 border-b last:border-b-0">
<span text={m.$transaction.description} />
<span text={m.$transaction.amount} />
</div>
</Repeater>
</div>
</Repeater>
</div> Checking
Groceries-85.5
Salary3500
Electric bill-120
Savings
Transfer in500
Interest12.5
Configuration
| Property | Type | Description |
|---|---|---|
records | Prop<any[]> | An array of records to be displayed |
recordAlias | AccessorChain | Alias used to expose record data. Defaults to $record. |
indexAlias | AccessorChain | Alias used to expose record index. Defaults to $index. |
sortField | StringProp | A binding used to store the name of the field used for sorting the collection. Available only if sorters are not used. |
sortDirection | Prop<"ASC" | "DESC"> | A binding used to store the sort direction. Available only if sorters are not used. Possible values are "ASC" and "DESC". Defaults to "ASC". |
sorters | SortersProp | A binding used to store the sorting order list. This should be an array of objects with field and direction properties (equivalent to sortField and sortDirection). |
sortOptions | object | Options for data sorting. See Intl.Collator options for more info. |
filterParams | StructuredProp | Parameters that affect filtering |
onCreateFilter | function | Callback to create a filter function for given filter params |
onTrackMappedRecords | function | Callback function to track and retrieve displayed records. Accepts new records as a first argument. If onCreateFilter is defined, filtered records can be retrieved using this callback. |
keyField | string | Field used to get the unique identifier. Improves performance on sort operations. |
cached | boolean | Set to true to enable caching for improved performance on large datasets |