Velo Repeaters: Understanding the Scope of Selector Functions
- Global Scope Selectors
- Repeated Item Scope Selectors
Global Scope
The $w()
function that is available to your Page and Site code selects elements in the global scope.
For example, here templateText
will be the text
value of the myRepeatedText
element from the repeater's item template.
$w.onReady( function () {
let templateText = $w("#myRepeatedText").text;
} );
For example, here the item template will change so that "New Text"
will be the text
value of the myRepeatedText
element. Also, all existing repeated items will have the text
value of their myRepeatedText
element set to "New Text"
.
$w.onReady( function () {
$w("#myRepeatedText").text = "New Text";
} );
And here the item template will change so that the myRepeatedImage
element is hidden. Also, all existing repeated items will have their myRepeatedImage
element hidden.
$w.onReady( function () {
$w("#myRepeatedImage").hide();
} );
Repeated Item Scope
There are two instances where you get a repeated item scope selector:
- The
$item
parameter of theforEachItem()
,forItems()
, andonItemReady()
event handlers. - When calling the
$w.at()
function and passing it anevent
whosecontext
is"COMPONENT_SCOPE"
. This is usually done in an event handler that handles events on an element inside a repeater.
For example, here when the myRepeatedImage
element is clicked, the text
value of the myRepeatedText
element from the repeated item where the image was clicked will be changed to "Selected"
. All the other myRepeatedText
elements in the other items of the repeater will not be affected.
$w.onReady( function () {
$w("#myRepeatedImage").onClick( (event) => {
let $item = $w.at(event.context);
$item("#myRepeatedText").text = "Selected";
} );
} );
Example

There are several ways a user can select elements:
- Click the selectAll button to select all the items.
- Click the selectLeft or the selectRight buttons to select all the items in the left or right column.
- Click a repeatedImage instance to select the item with that image.
1$w.onReady( () => {
2 $w("#selectAll").onClick( (event) => {
3 $w("#itemSelected").text = "Selected";
4 $w("#numSelected").text = $w("#myRepeater").data.length.toString();
5 } );
6
7 $w("#repeatedImage").onClick( (event) => {
8 let $item = $w.at(event.context);
9 if($item("#itemSelected").text === "Unselected") {
10 $item("#itemSelected").text = "Selected";
11 $w("#numSelected").text = (Number($w("#numSelected").text) + 1).toString();
12 }
13 else {
14 $item("#itemSelected").text = "Unselected";
15 $item("#numSelected").text = (Number($w("#numSelected").text) - 1).toString();
16 }
17 } );
18
19 $w("#selectLeft").onClick( (event) => {
20 selectColumn(0, 2);
21 } );
22
23 $w("#selectRight").onClick( (event) => {
24 selectColumn(1, 2);
25 } );
26} );
27
28function selectColumn(columnIndex, numColumns) {
29 $w("#myRepeater").forEachItem( ($item, itemData, index) => {
30 if(index % numColumns === columnIndex && $item("#itemSelected").text === "Unselected") {
31 $item("#itemSelected").text = "Selected";
32 $item("#numSelected").text = (Number($w("#numSelected").text) + 1).toString();
33 }
34 } );
35}
First, let's look at the onClick()
event handler for the selectAll
button.
1$w("#selectAll").onClick( (event) => {
2 $w("#itemSelected").text = "Selected";
3 $w("#numSelected").text = $w("#myRepeater").data.length.toString();
4} );
All selectors in this snippet are global selectors. That means that the selection of the itemSelected
text element on line 2 is from the global scope. So when its text
value is set, the text
value of the itemSelected
element in the repeater's item template and the text
values of all the repeated itemSelected
elements in all of the repeated items are set to "Selected"
. This is what allows us to "select" all the items in one line of code. (We have also changed the item template. But since we will not be creating any new items, the change is of no consequence.)
Next, let's look at the onClick()
event handler for the repeatedImage
element.
1$w("#repeatedImage").onClick( (event) => {
2 let $item = $w.at(event.context);
3 if($item("#itemSelected").text === "Unselected") {
4 $item("#itemSelected").text = "Selected";
5 $w("#numSelected").text = (Number($w("#numSelected").text) + 1).toString();
6 }
7 else {
8 $item("#itemSelected").text = "Unselected";
9 $item("#numSelected").text = (Number($w("#numSelected").text) - 1).toString();
10 }
11} );
On line 2 we create a repeated item scope selector. That means all the selections using that selector in the body of the function are repeated item scope selections. So when we select a repeated element, such as the itemSelected
text element, we are selecting the individual instance of that element that is in the same repeated item as the image that was clicked. All the other itemSelected
elements in the other items of the repeater will not be affected.
Finally, let's look at the onClick()
event handler for the selectLeft
and selectRight
buttons.
1$w("#selectLeft").onClick( (event) => {
2 selectColumn(0, 2);
3} );
4
5$w("#selectRight").onClick( (event) => {
6 selectColumn(1, 2);
7} );
Both of these event handlers call the selectColumn()
function which "selects" all of the items in a given column.
1function selectColumn(columnIndex, numColumns) {
2 $w("#myRepeater").forEachItem( ($item, itemData, index) => {
3 if(index % numColumns === columnIndex && $item("#itemSelected").text === "Unselected") {
4 $item("#itemSelected").text = "Selected";
5 $item("#numSelected").text = (Number($w("#numSelected").text) + 1).toString();
6 }
7 } );
8}
The $item
parameter of the forEachItem()
function is a repeated item scope selector. That means all the selections using that selector in the body of the function are repeated item scope selections. So when we select the itemSelected
text element, which is a repeated element, we are selecting the individual instance of that element for the specific item of the current iteration of the forEach
loop. All the other itemSelected
elements in the other items of the repeater will not be affected.