Custom Tree Widgets using Repeaters

Hey guys–Ben from Axure Support here with a “fun” post on the great uses of repeater widgets and some useful interactions/logic that can go with it :grinning:.

Axure RP has tree widgets built in but sometimes you just want to customize every single aspect of it. Fortunately, you can customize and create virtually anything in Axure RP and if you want to manually create a tree widget out of a repeater, it’s definitely possible! Although it uses some advanced techniques, it’s definitely something you can try.

Setting up the tree structure

Custom Repeater Tree Widget.rp (55.6 KB)

First, we’ll need to set up the repeater so it can look like a tree widget. I started with creating the contents and then making it a repeater. In my example, it’s just a rectangle widget. You can now add values to the repeater dataset to create the tree structure you want. Then on the repeater widget itself, you’ll want to add an “Item Loaded > Move” interaction that moves the contents. I just chose 20 X values for simplicity.

At this point, all of our rectangles will be moved to the right by 20 units but we want more control as to which ones are moved. Generally in tree widgets, child elements are moved according to their rank which I found can be determined by the number of periods. For example, one period indicates it’s the first child and two periods indicate it is a “grand” child. To find out whether it has a period, we’ll add conditional logic and the .indexOf(".") function which looks for where the first instance of a period is. If there isn’t a period it will return -1. Be sure to use local variables correctly to target the text on the repeater item widget.

Now for the grandchildren (or two periods) we can duplicate the interaction and add to the condition. We’ll want to create an expression that ignores the first period as now we’re looking for the presence of a second one. We’ll again use the .indexOf(".") function which will tell us the index of the first period, but we’ll add +1 so this gives us the location of the character after the period. Then we will use the .slice() function with this new index to essentially remove the first period and everything before it and spits out our new (one period-less) value. Our current expression will look something like LVAR1.slice(LVAR1.indexOf(".")+1) and for purposes of this discussion let’s call it, DVAR. With our newly sliced and trimmed value if we use the .indexOf(".") function again to look for a second period and if it has one, the value will be above -1. This will allow only the grandchildren to be moved again.

All said and done, your conditions may look like this for the initial setup.


If you have more descendants, then you can add another DVAR.slice(DVAR.indexOf(".") +1) expression with DVAR being the same expression as used above. It can get a little long and unwieldy for more descendants because we can’t create or store internal variables within this value builder but I have included an example just in case you wanted to see what it may look like.

Making it collapsable

Now we still need to make the elements collapse when clicked. To determine whether a row is a child element, we will need to assess the entire repeater and each row individually. We can use a neat little repeater trick that involves an external listener widget that can affect the repeater as a whole. For this, I added a placeholder widget that has a “Loaded > Rotate > By 0” interaction and targets our repeater tree widgets. The reason for this is we don’t want our repeater to actually be rotated but we do want an interaction to be triggered on the widget within. You can also use something like “Move by 0,0” as well!

So moving on to the tree widget inside, we can add a “Click or Tap > Set Variable Value” in order to set a global variable of the text on the widget that we click. This will be used to help determine what the child elements are. Then we will add a “Fire Event” action to fire our placeholder’s “Loaded” event.

We can now add a “Rotated > Show/Hide > Toggle > This” interaction to connect back to our listener widget. Generally, child elements are anything that has the same number but has an additional period after. With this logic in mind, we can add a condition that matches the global variable (which we have set as the text of what we’re clicking on), to any repeater text that is the same but with an extra character length. The condition will have an expression that looks like This.text.slice(0, (GVAR.length +1)). It should look something like below:


You can apply some fun style effects or apply these interactions to other widgets instead to customize your tree widget to look however you want. You can also disconnect these widgets from the repeater and use the data internally while adding other content instead.

And there you have it! A custom tree widget made from a repeater. I also included several inline links for relevant topics to our Axure Docs as well so feel free to check those out for more information on the various widgets or expressions I used.

Of course, if anyone else has any questions or better ways to do so, please feel free to let us know.


Hey Axure Team Great Job !

1 Like