-
Notifications
You must be signed in to change notification settings - Fork 1
Repeater
Repeater management in Let's Role can be tricky and I found that the available features were not sufficient. When I tried to handle them I found a lot of edge cases that made me definitely decide to build LRE.
In LRE 7, repeaters have many more methods to handle and many custom events to help you do what you want.
- entry : this is how LRE calls a repeater line. In Let's Role it is called repeater element
- entryId : this is the index of every component inside a repeater. It is in fact the id of the entry in the repeater.
repeater.provider(): DataProvider
This method will return a DataProvider whose data are sync on the repeater value. As soon as the repeater has changed the returned DataProvider will be refreshed.
You can then use it with the DataProvider methods.
each(column: string, callback: (component: Component, data: Object, entryId: string): undefined
each(callback: (entry: Object, data: Object, entryId: string) => void): undefined
repeater.each() is an easy way to run some code on each entry.
If you specify a string as first parameter, this method helps you to loop on each component that has its id equal to the string.
If the first parameter is a function, you will have access to each entry.
Both codes below are equivalent :
repeater.each("name", function (componentName, entryData, entryId) {
log("Repeater index : " + entryId + " has the name '" + componentName.value() + "'");
});
repeater.each(function (entry, entryData, entryId) {
const name = entry.find("name");
log("Repeater index : " + entryId + " has the name '" + name.value() + "'");
});repeater.map(callback: (data: Object, key: string)): Object
This method transforms each data of the repeater value using the given function.
// repeater data is like {1: {type: "axe", damage: "2d6"}, 2: {type: "knife", damage: "1d6"}}
const output = repeater.map(function (entryData, entryId) {
return entryData.type + " " + entryData.damage;
});
// output is like {1: "axe 2d6", 2: "knife 1d6"} repeater.setSorter(cmp: Component | Group | string, column: string): void
If you want to use a repeater like a table, and put some labels as Column title that can sort the repeater ascending or descending, you can use repeater.setSorter(). The sorting method is a simple comparison between component values.
Examples :
repeater.setSorter(sheet.get("titleItemType"), "type"); // click on the title "Type" will sort by name
repeater.setSorter("iconHouse", "chkHouse"); // click on the icon house will sort by a checkbox
repeater.readOnly(readonly: boolean = true): void
This simple method is an easy way to remove the "Add" and "Edit" buttons in the repeater. It accepts a boolean as parameter (which can be a dynamic value, like a checkbox component).
Example :
sheet.get("repeater").readOnly(sheet.get("checkboxReadonly"));
repeater.add(data: Object, entryId?: string): void
repeater.remove(entryId: string): Object
LRE provides to easy methods to add or remove an entry by code.
Let's role provides no information about the newly created edit view when you click on "Add" if this "Editable View" does NOT contain at least one Choice.
In this case the events init and initwrite can not be triggered.
As soon as one "Editable view" 's component value is changed, the entry is available and you might consider it is too late to initiate it.
👉🏻 I encourage you to always have at least one choice in the "Editable views" you need to initiate.
If you don't need Choice in your "Editable view", I suggest to add one anyway (with correct table and label properties), and hide it using the class d-none in the Classes component property.
repeater.on("entrychange", function (
repeaterComponent,
entryComponent,
entryId,
newEntryData,
oldEntryData) {
});This event is trigger as soon as an entry have his data changed. It there are no changes this event is not triggered.
repeater.on("save", function (
repeaterComponent,
entryComponent,
entryId,
newEntryData,
oldEntryData) {
});This event is triggered when you click on the "Done" button when finishing creating/editing an entry.
oldEntryData is equal to {} (empty object) if it is a new entry.
repeater.on("initread", function (
repeaterComponent,
entryComponent,
entryId,
newEntryData,
oldEntryData) {
});initread is triggered as soon as you add this event handler to the repeater (ie. at the sheet init), and as soon as you change the entry data, or create a new entry.
oldEntryData is equal to {} (empty object) if it is a new entry or at the event creation.
This event is very useful in order to set event handlers (like click) on component in the repeater "Readable view" from the init of the sheet and even after changing things in the repeater.
It is also more optimized as it will be triggered only when the entry data is effectively changed, which can prevent some useless computations and cascading changes in the sheet.
repeater.on("initedit", function (
repeaterComponent,
entryComponent,
entryId,
entryData) {
});This event is triggered when the "Editable view" is displayed (when you click on the "Add" button or the "Edit" button).
See here to understand that this event can be NOT triggered because of a Let's Role specificity.
repeater.on("init", function (
repeaterComponent,
entryComponent,
entryId,
entryData) {
});This event is triggered the first time the "Editable view" is displayed for an entry.
See here to understand that this event can be NOT triggered because of a Let's Role specificity.
repeater.on("edit", function (
repeaterComponent,
entryComponent,
entryId,
entryData) {
});This event is triggered when you click on the "Edit" button in an entry.
repeater.on("delete", function (
repeaterComponent,
entryId,
oldEntryData) {
});This event is triggered when you click on the "Delete" button in an entry.
Note that the function doesn't receive the entryComponent (as it is deleted).
repeater.on("new", function (
repeaterComponent,
entryComponent,
entryId,
newEntryData,
oldEntryData) {
});This event is triggered after you click on the "Done" button for a new entry. It is not triggered for modified entries.
oldEntryData is always equal to {} (empty object).
repeater.on("dataChange", function (repeaterComponent) {
});This event is triggered as soon as at least one entry was modified after clicking on "Done" or "Delete" buttons (deleted entry, new entry, entry with modified data).