Components and Layout · Lesson 2.3
Repeating content with the Repeater in UI Builder
- UI Builder
- Data resources
The problem it solves
Suppose you want to show an agent’s open incidents as cards, each with a number and a short description. You could add three cards by hand. But tomorrow the agent has five incidents, and the day after that, none. You cannot know in advance how many cards the page needs, and you certainly cannot rebuild the page every morning.
What you really want to say is: “Here is what one card looks like. Make one for each incident, however many there are.” That is exactly what a Repeater does. It is a loop, the same idea as a for loop in a script, but built visually.
The two halves of a Repeater
Every Repeater has two parts, and both must be set up before anything useful appears.
| Part | What it is | Where you set it |
|---|---|---|
| The list | The Data array property: the items to loop through, usually records fetched from a table | On the Repeater’s Configure tab |
| The template | The components you place inside the Repeater, such as a Heading and some text | Add them under the Repeater with + Add content |
A Data array is an ArrayA list of items in a fixed order, such as a list of records returned by a query. In JSON it is written inside square brackets.Learn more : a list of items in order. Most of the time each item is a record with fields, like { "number": "INC0010031", "short_description": "VPN drops every hour" }. A list with three items means three copies, a list with zero items means nothing is drawn.
@item.value: each copy reads its own item
This is the part that makes a Repeater useful. When a component inside a Repeater binds a property to data, it can choose Repeater as the data type. That gives it @item.value, which means “the item this copy belongs to”.
So a Heading inside the Repeater with its label bound to @item.value.number.displayValue shows a different number in every copy:
| Copy | Its item | What the Heading shows |
|---|---|---|
| 1st | The first incident in the list | INC0010031 |
| 2nd | The second incident | INC0010032 |
| 3rd | The third incident | INC0010033 |
Read the binding from left to right: @item.value is the current item, .number is its Number field, and .displayValue is that field the way a person should see it. Records from a data resource carry both the stored value and the display value for each field, which matters for fields like dates and references, where the stored value is not what a user wants to read.
Press Play to watch a Repeater go from an empty list to a set of cards, including the moment it makes three identical copies.
Step 1 of 6 · Data
Fetch the records
The page has a data resource, Look up multiple records, set to the Incident table. It returns three incidents. Nothing is on the screen yet: the data is just sitting in the page, waiting for a component to use it.
results: [ { number: INC0010031, short_description: "VPN drops every hour" }, { number: INC0010032, short_description: "Outlook keeps asking for password" }, { number: INC0010033, short_description: "Printer on floor 3 shows paper jam" } ]- Data array
- (not set)
- Template
- (empty)
- Heading label
- -
- Copies on screen
- 0
Step 2 of 6 · Repeater
Add a Repeater and give it the list
You add a Repeater and bind its Data array property to the data resource's results. The Repeater now knows it has three items to loop through, but it has nothing inside it to repeat, so the screen is still empty.
Data array = @data.look_up_multiple_records_1.results- Data array
- 3 incidents
- Template
- (empty)
- Heading label
- -
- Copies on screen
- 0
Step 3 of 6 · Template
Put a Heading inside it
You add a Heading inside the Repeater. Whatever sits inside a Repeater is the template, and it is drawn once for every item. Three items, so three Headings appear. But they all say the same default text, because the Heading is not reading anything from its item yet.
- Data array
- 3 incidents
- Template
- Heading
- Heading label
- "Heading" (typed in)
- Copies on screen
- 3 identical headings
Step 4 of 6 · Bind
Bind the Heading to its own item
You bind the Heading's label, choosing Repeater under Data types. @item.value means "the item this copy belongs to". The first copy reads the first incident, the second copy the second, and so on. Now every heading shows a different number.
Label = @item.value.number.displayValue- Data array
- 3 incidents
- Template
- Heading
- Heading label
- @item.value.number.displayValue
- Copies on screen
- INC0010031, INC0010032, INC0010033
Step 5 of 6 · Bind
Add the description underneath
You add a Stylized text component under the Heading, still inside the Repeater, and bind it to the short description the same way. Each copy is now a small card: a number with its description below it.
Text = @item.value.short_description.displayValue- Data array
- 3 incidents
- Template
- Heading + Stylized text
- Heading label
- @item.value.number.displayValue
- Copies on screen
- 3 cards, each with its own number and description
Step 6 of 6 · Result
A new incident arrives
Someone logs a fourth incident. When the data resource fetches again, the list has four items, and the Repeater draws four cards. You did not touch the page at all. That is the whole point: you design one card, and the data decides how many there are.
- Data array
- 4 incidents
- Template
- Heading + Stylized text
- Heading label
- @item.value.number.displayValue
- Copies on screen
- 4 cards
Where the list comes from
A Repeater does not fetch records itself, just like the Record List in your first challenge did not. The list comes from a Data resourceSomething you add to a UI Builder page to fetch data, such as a list of records, so components can show it.Learn more , which you add in the Data and scripts panel.
For a list of records, the data resource is Look up multiple records. You set its Table, for example Incident, and Max results, for example 5. Then you bind the Repeater’s Data array to its results, which looks like this:
@data.look_up_multiple_records_1.results
@data means “a data resource on this page”, look_up_multiple_records_1 is the ID of the one you added, and results is the list of records it returned. You will learn data resources and binding in full in the next module. For now, it is enough to recognise the pattern: @data fills the Repeater, @item fills what is inside it.
Repeater or Record List?
You already know the Record List, which also shows many records. They solve different problems:
| Record List | Repeater | |
|---|---|---|
| What you get | A ready-made table with columns, sorting, pagination and row selection | Exactly the design you build, once per item |
| How much setup | A table and a filter on its controller | A data resource, the Data array binding and a binding on every component inside |
| Best for | Working through lots of records in a standard list | Cards, tiles, buttons, badges and other custom designs for a short list |
| Large lists | Handles thousands of rows by showing one page at a time | Draws every item at once, so keep the list short |
A good rule: if users need to sort, page through or select records, use a Record List. If you want the records to look a particular way and there are not many of them, use a Repeater.
See it in your instance
- Open UI Builder in your PDI (Personal Developer Instance)A free ServiceNow instance you get from developer.servicenow.com to practise on safely.Learn more and open a test page in the experience you created earlier.
- Open Data and scripts, select + Add data resource, search for Look up multiple records and select Add. Set Table to Incident and Max results to 5, then close the window.
- Select a container or a column layout, then add a Repeater from + Add content.
- On the Repeater’s Configure tab, choose None - Configure the component manually if you are asked. Then hover over Data array, select the Bind data icon, choose Data resource under Data types, select the Look up multiple records 1 pill, make sure the pill view reads
@data.look_up_multiple_records_1.results, and select Apply. - Under the Repeater, select + Add content and add a Heading. Look at the stage: you should see five identical headings.
- On the Heading’s Configure tab, choose None - Configure the component manually if you are asked. Bind its Label: choose Repeater under Data types, select the value pill, then number, and add
displayValueso it reads@item.value.number.displayValue. Select Apply. - Save and Preview the page. Five headings, five different incident numbers.
Practice: Repeater or Record List?
Both show many records. A Record List gives you a ready-made table with sorting and pagination. A Repeater draws any design you like, once per item. Pick the better fit for each request.
Show the five newest announcements as cards, each with a title, a date and a short summary.
Answer: Repeater. Cards are a custom design, not a table. Design one card inside a Repeater and it is drawn once per announcement.
An agent needs every open incident in a table they can sort by priority and page through.
Answer: Record List. Sorting, columns and pagination are built into the Record List. Rebuilding them with a Repeater would be a lot of work for a worse result.
A row of small tiles, one per assignment group, each showing the group name and how many tickets it has.
Answer: Repeater. A tile per item, in a layout you choose, is exactly what a Repeater is for.
A full list of all 4,000 configuration items, filterable by class.
Answer: Record List. Thousands of rows need pagination. A Repeater draws every item at once, which would make the page very slow.
The last three comments on a record, shown as chat-style bubbles with the author's name.
Answer: Repeater. A short list of items with a custom look. One bubble design, repeated for each comment.
A manager wants to see their team's change requests with the usual columns: Number, Short description, State and Planned start.
Answer: Record List. A standard table of records with standard columns. The Record List does it with a table and a filter, no binding needed.
A "Quick links" panel with one button for each link stored in a custom table, around six of them.
Answer: Repeater. Put one Button inside a Repeater and bind its label to each item. Add a seventh link to the table and a seventh button appears.
Users must be able to tick several records at once and run an action on all of them.
Answer: Record List. Selecting rows and acting on them is a built-in Record List feature. With a Repeater you would have to build all of that yourself.
What’s next
You can now show any design once per record: bind a Repeater’s Data array to a data resource, place a template inside it, and bind each component to @item.value. In the next lesson, Styles, themes and presets, you will make those components look the way you want, without fighting the theme of the workspace they live in.
Quick check
A Repeater's Data array has four items. Inside it is a single Heading whose label is typed in as 'New ticket'. What appears on the page?
Show answer
Four headings, all saying 'New ticket'.
The Repeater draws its contents once per item, whether or not those contents use the item. Four items means four Headings. Because the label is typed in rather than bound to @item.value, every copy shows the same text. Bind the label to a field of the item, such as @item.value.number.displayValue, to make each copy different.
Was this lesson helpful?
Thanks! Glad it helped. 🙌
Thank you. We will use this to improve the lesson.
Spotted a mistake, or a step that looks different in your instance?