It's my third post about event handling in repeated items. I show you a way that always has been in the documentation. I'm surprised why I hadn't noticed that before?
Yes, and again the event handling in Repeater. For me, the event handling of the repeated items was maybe the first confusion in my Velo projects.
I wrote two articles about it, you can find them in this blog:
- Event handling of Repeater Item - here we considered how to handle events in the repeated items and we created a primitive helper function.
- The utils for repeated item scope event handlers - here we created a more smart code snippet that can automatically receive parent Repeater item data from the event.
The main idea of these two articles, we shouldn't nest an event handler in any Repeater loop. It could be a reason when a callback function runs a few times by one event.
The Velo documentation is supposed to use the next way for handling events using event context.
Velo: Understanding the Scope of Selector Functions
$w.onReady(function () {
$w('#myRepeatedImage').onClick((event) => {
const $item = $w.at(event.context);
$item('#myRepeatedText').text = 'Selected';
});
});
In most cases, it's enough. But, if we need to receive an item data object or index of the fired item, the documentation provides something like this:
Velo API Reference: Retrieve Repeater item data when clicked
$w.onReady(function () {
$w('#repeatedContainer').onClick((event) => {
const $item = $w.at(event.context);
const data = $w('#myRepeater').data;
const clickedItemData = data.find((i) => i._id === event.context.itemId);
const clickedItemIndex = data.findIndex((i) => i._id === event.context.itemId);
console.log('itemData', clickedItemData);
console.log('index', clickedItemIndex);
});
});
It does not look bad. But we want to have a better 😊
Method forItems()
The Repeater has the forItems()
method that allows us to run specific repeated items with the given list of IDs. I have never used it before. Previously, if I wanted to rerender some Repeater items then I just used the forEachItem()
method. forItems()
allows us to run the callback function for specific items, not all.
Velo API Reference:
Use the
forItems()
function to run a function on a specified list of repeated items. You can use the callback function to update or pull information from the specified repeated items
In the documentation, we can see the next example, which runs changes for two items by IDs.
Velo: Update data in some of a repeater's repeated items
$w('#myRepeater').forItems(['item1', 'item4'], ($item, itemData, index) => {
$item('#repeatedImage').src = itemData.img;
$item('#repeatedText').text = itemData.description;
});
Really, it's a very cool opportunity. It's always has been in the documentation. Why I hadn't noticed that before?
For example, we can solve our current issue with receiving item data.
Velo: Retrieve items scope selector function, item data, and index
$w.onReady(function () {
$w('#repeatedButton').onClick((event) => {
// Run callback for item ID from event context
$w('#myRepeater').forItems([event.context.itemId], ($item, itemData, index) => {
$item('#myRepeatedText').text = 'Selected';
console.log('itemData', itemData);
console.log('index', index);
});
});
});
Magic. For me, it's a very expressive code. And it's a good alternative to all known methods that I use before, like: repeater-scope npm package.
Resources
- Velo: Understanding the Scope of Selector Functions
- Get the element context in which an event was fired
Top comments (0)