Source on How to Use Repeaters and Local Variables?

All,

With all due respect to the online help writers, the help on how to use some of the functions in Repeater, and Local Variables, is very opaque. I know, it’s not you, it’s me. The Help topics just aren’t connecting the dots for me.

Generally, what I want to know is how do I take a repeater function and use it outside the repeater?

What I specifically am trying to do is:

  • On applying filter, take the itemCount (count of visible items) and
  • set that value as the text for a different widget (text field, label, whatever)…

…but I want to be able to use this concept more generally than just this specific case.

It’s important, since I’m trying to beat back the forces of Sketch and Figma (shudder).

Thanks in advance.

No, it’s them. Just search this forum for “repeater” and see all the Axure users, including experts and “Si Fu’s” who have been confused by repeaters. Likewise, discussions about Local Variables and Axure’s built-in variables and “hidden functions.” To be fair, the documentation is a decent introduction, and it is worth your time to go through the tutorials (There are several for repeaters in the menu on that page), but for sure, many questions and mysteries will remain. That’s where this forum comes in!

Here is a sample file built from a recent forum post about repeaters. I’ll use it to demonstrate some filtering basics both within and outside of the repeater:
https://28cngv.axshare.com
basic repeater filtering.rp (74.1 KB)

I don’t claim to be an expert on repeater widgets, but I have used them successfully–eventually–in many situations. I would say the best way to understand this concept more generally is to get very detailed on this specific case, then other cases, then others, then test out stuff just to see what it does, then try answering other’s questions on this forum, etc. (just like you would gain knowledge in algebra, physics, chemistry, etc.) …And the best way to get specific here is to upload an .rp file and let forum users offer solutions and explanations. Of course, you can and should search the forum for your questions–chances are it’s been asked and answered already. You can also email support@axure.com and attach your .rp file.

That said, let’s see if we can start here… When you say, “repeater function” what do you mean? Applying a filter within a repeater versus outside a repeater? Or, “any and all” actions which can apply to repeaters? In general, anything you can do within a repeater you can do outside of that repeater, with some caveats and gotchas. One of the first tricks to learn is how to properly point to that repeater widget when “performing functions” on it --whether within or outside of the repeater. That’s where Local Variables come in, and is a common source of confusion and bugs.

So, my example above has a repeater list, named “repListDeparting” with 14 rail stations of varying distances away from your current location (I think somewhere in Scotland?) If you look at the interaction code for the repeater, the Item Loaded event sets the text on two widgets, according to the “Location” column cell and the “Distance” column cell in the repeater datasheet (located on the Style pane.) It also sets the text on two external widgets, “ItemCount” and “visibleItemCount”. I set it up this way so that any time the repeater is “touched” or in other words, “reloaded” (actions such as applying a filter, sorting, updating/adding/deleting a row, etc.) the count values would be updated automatically. This is one simple way to solve your specific question.

As with most things Axure, there are many ways to achieve the same results. I could have instead added an action to one of the “Filter” buttons to set the text of these widgets directly–and in fact, I did, just to show you how this would be done. Take a look at the code for the “btnFilter3” widget:

image

  • Adding a filter is easy and straightforward–but the logic of those filters can be tricky sometimes. First, I click the Add Filter action and select a Target (automatic in this case because there is only one repeater widget on my page.)
  • Then I enter an optional name. I do this because I want to be able to remove this specific filter later.
  • Then I supply the Rule. In this case, I want to show only the stations which are less than 3 miles away. I can point to any of the columns in my repeater and evaluate their contents against my desired rule (technically, my rule’s “delimiter” which is 3.) I can either type in my “magic formula” directly, or click the little “fx” button to the right of the Rule field and build it with some help from Axure. This opens the Edit Value dialog:

To find out which repeater properties I can access, I click the “Insert Variable or Function…” link and spin open the Repeater section:

Aha! I can click on “item.Distance” as that is the column I want to evaluate. This fills in my Rule value:

…which i can complete by adding “< 3” inside the “expression brackets”, to get [[ Item.Distance < 3 ]] …all of which means, “the item value in column “Distance” is less than 3”, and that is my Filter Rule. If this expression is true, the repeater item (row) will be shown.

OK, so my filter works. The next action on that filter button sets the text of my “Count” widgets, which is actually redundant because the repeater does this automatically. It points out a few things, though:

  • There would seem to be a bug in that the .VisibleItemCount property and the .ItemCount property have the same value (9; stations less than 3 miles away.) But it turns out that filters effectively do remove items from the repeater list (but not the repeater’s datasheet.) The .VisibleItemCount property really only applies to pagniation, which we aren’t dealing with here.
  • How to refer to a repeater widget with a Local Variable. Again, click the little fx button to the right of the Value field in this Set Text action. I set this up by clicking the Add Local Variable link, selecting a type of “widget” and then selecting the widget I want to “point to” --which is my repeater. By default, the local variable is named, “LVAR1” so in my expression, [[LVAR1]] is a pointer to my repeater. The “double square brackets” are used to denote this as a logical expression instead of regular text. (This is an important concept to grasp, so [[1+2]] equates to 3, but 1+2 equates to the text string, “1+2”. Get it?) Now, I can access any available property belonging to my repeater by using a period or “dot” and the name of that property. In this case, I want “.visibleItemCount” --which I can type in directly, or click the Insert Variable or Function link and pick it out of a list of all the repeater properties. One other thing to note here… if you first select the property from this list, before creating your local variable, by default it would read, [[LVAR1.VisibleItemCount]] but LVAR1 would not point to anything, so it would equate to a blank string–not what you intended.
  • If you look at the next statement in the Set Text action, it sets the text of widget itemCount to "[[r.itemCount]]" …and if you click into that fx value, you will see that I named its Local Variable as “r” instead of “LVAR1” --just to show you this is possible. I could have used just about any string for my variable name, like, “MyRepeater” but be sure not to use spaces, special chars or “reserved words” like function names.

So, that is how you can go about creating filters and updating list counts from outside the repeater.

Now, I’ll describe how to do this from inside a repeater. If you Preview the prototype and hover over the repeater list, you’ll notice a text value is set (for a widget outside of and to the right of the repeater named, “ItemHovered”), and if you click on this group it will select it and update another text value (for the widget named, “ItemSelected”). Also, there are styles defined for :mouseover and :selected. You can drill into the repeater to see how all this is set up. It is fairly straightforward and easy (once you get used to it.) In the Axure editor, you can double-click the repeater widget to “drill into it, in place” --this will show the interactions for the repeater itself. Click again and you will select the front-most widget in the repeater cell–in this case, a group of widgets named, “rowGroup”. Here you can see the style properties I set, (:mouseover and :selected) and the events (Click or Tap, Mouse Enter, and Mouse Exit). If you further “click into” this group, you will find the back-most widget named, “rowBg” where I set the Selected event to set the text of “ItemSelected” widget to [[Item.Location]] --which means the value in this item’s Location column. So, lots of things you can do from within a repeater to affect widgets outside that repeater.

I also set up a filter within the repeater. If you double-click on the distance value in the list, the repeater will be filtered to show only distances less than or equal to that distance. To see the code for this, select the widget named, “Distance” in the repeater cell, then click the filter:

  • The TARGET for this filter is “repListDeparting” which is the name of this repeater
  • The name of this FILTER is “distanceFilter” --which I didn’t have to name, but never hurts…
  • The Rule is [[ TargetItem.Distance <= Item.Distance ]] --and this points out a tricky little detail about using filters from within a repeater. If you’ve ever seen the movie, Inception, it’s kind of like that :smile Think of a filter as a function which looks at each row of a repeater–technically, the values in the repeater datasheet–and evaluates the logical expression in the Rule for each and every row. When a filter is created inside a repeater that means the repeater is filtering itself, and it needs a way to distinguish “the item being looked at” and “the current item–the one that is calling the “filter function” " …and I can only hope that makes sense :stuck_out_tongue_winking_eye: So, TargetItem refers to “each and every row in the repeater” and Item refers to “this row” …thus, my rule means, for each and every “Distance” value, show that row if it is less than or equal to the “Distance” value in this row.”

I hope this helps your understanding. I’ll stop now before I get too far into the details (ha ha :wink:)

5 Likes

Hi!

To reiterate, it’s not you. The learning curve on the repeater is steep withn a product whose learning curve is steep. I’ve used repeaters daily for years, and I still find tricks that surprise me.

I wrote a Medium article on the repeater a while back. The primary focus is how powerful OnItemLoad (or whatever it’s called now) can be, and it includes an introduction to expressions and repeater item properties. Without understanding what exactly happens during OnItemLoad, fully understanding the repeater is impossible.

Filtering is a topic of its own, and is vastly powerful. And there’s a topic that deals with accessing/manipulating the repeater from outside of the repeater called “the listener method,” which you pretty much have to Google. When I’m not on my phone, I’ll post some forum links.

3 Likes

Excellent answer (although I need to re-read it for more detail). And thank you. I have actually figured out several of the things you commented on (I, too, learn by doing!) - I’m getting a repeater to do most of what I want it to do, within the repeater.

Just to clarify - when I refer to “Repeater functions”, I’m referring to the bits of code that return values from the current state of a repeater - functions like “ItemsLoaded” or “IsMarked”, that kind of thing.

So what I’m looking to do (and I realize an RP file would make things much clearer, and I’ll work on getting that together here) is something like this:

  • I have a repeater with n rows. I can set filters that will cut the list down to some smaller set of rows - let’s call that o.
  • I have a piece of text - let’s call it my Row Counter - in a separate panel, outside the repeater.
  • I want to get the of rows appearing in the repeater to display in the RowCounter, when some triggering event (the click of a “Filter” button, let’s just say) happens.

To do this, I know the button click event needs to get the current row count from repeater.itemCount, and put it into the Row Counter. The dox from Axure and what I’ve read on the forums seem to indicate I need to get the itemCount value into a local variable, and then push the local variable to the Row Counter. I’m working on figuring out the how.

I’ll re-read your response in a bit here. Thanks!

Thanks! I’ll read the Medium piece, and the links, whenever they post.

Thanks again!

The way I built the repeater example in my previous post does just that, automatically, whenever the repeater is filtered. The Item Loaded event (was OnItemLoad in RP8) includes an action to Set Text of a widget outside the repeater. So, as each item (row in the repeater) loads, the text of that widget gets updated. In the example, there are 14 repeater items, so initially the text widget (“ItemCount”) shows “14”. If you filter the repeater with the result being 9 items, then only 9 repeater items load and the text on “ItemCount” shows “9”. That’s it–you don’t need to do anything extra when you add or remove a filter. The repeater just takes care of it itself.

Now, this method assumes the repeater knows about the external widget. If for some reason that is not the case, then you could either have the Item Loaded set the value of a global variable and then get that value after filtering, or your event which creates the filter can assign the text of any widget, or global variable by simply adding an action to Set Text or Set Variable Value and refer to the repeater’s .itemCount property. See the interaction code for the “btnUpdateCounts” widget in my example.

2 Likes

I’m having this mad “Eureka” moment right now, I was picking through the example you gave, but that clarified it immensely.

Thanks!

And yes, it’ll have to go through a global variable.

And boom - I got exactly what I was looking for with about ten seconds worth of puttering about in the repeater attributes.

Thanks!

Hi! Here’s a post on the repeater “listener” method. The post just below it has a file with examples from Gregor, which I found to be helpful.

1 Like

All,

Thanks for all the help. This has been far and away the most productive trip to Axure Forums ever.

I appreciate it!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.