Skip to main content

Exercise 2: Build the Interface and Pagination

Goal​

In this exercise, you'll add a data resource to query the database for a list of notes and add a repeater to the page to show those notes in a card view.

Add a Look up multiple records data resource​

  1. In UI Builder, find the Data and scripts panel in the bottom left corner of the page. This area has been redesigned in the Washington DC release to be more better organized and reduce clicks. Click +Add data resource

  2. Choose Look up multiple records and click Add.

  3. Rename the data resource by clicking the (i) icon at the top of the configuration panel next to the name of the data resource:

    • Data resource label: Look up notes

    • Data resource ID: look_up_notes

  4. Click Apply.

  5. Configure the rest of the data resource as follows

    • Table: Note [x_snc_killer_notes_note]

    • Filter: click Edit conditions and set the following conditions: User | is (dynamic) | Me

    • Fields (you'll have to add these one at a time):

      • Title

      • Text

      • Created

      • Category.color (make sure to use the next to Category right-arrow to show Color on the right)

  6. You should now see some JSON in the right-hand panel that shows you the values for all the fields you've added for about 40 note records. Close the Edit Look up notes dialog.

  7. Save the page.

Build the page out​

Now you'll add Layouts and Components to your page and connect your data resource to them. Layouts consist of column layouts and flex and grid containers and allow you to lay out your page without having to know too much CSS. You'll add components within the containers that will show the data returned by the data resource.

Add a Repeater​

In this section, you'll add a repeater component. A repeater is simply an iterator that will repeat over every element in an array. It is a great way to build out a list of cards as you'll be doing here. Use it similarly to a for loop in JavaScript, ngRepeat in AngularJS, or j:while in Jelly (for the oldtimers).

That means that if your data resource returns 10 records, you can show each record in whatever layout you want (grid, list, etc.), showing individual fields from each record.

  1. In the content tree on the left side of the builder above the Data and scripts panel, click +Add component under the Body Container and choose Single column under Layouts.

    Adding a column layout instead of a simple container gives you the option to add additional columns later, for example adding a left-hand menu. Consider how your page might change in the future and plan ahead when laying out your page.

  2. Now you'll add a repeater component within the new single-column layout. Use the +Add component button under Column 1 to add a repeater component.

    UI Builder also has right click menus that make it easy to insert components. Right click directly on the page you are building or in the contents panel to the left.

  3. In the configuration panel on the right-hand side of the page, choose None: Configure the component manually when presented with the preset options. Learn more about presets in the doc Automatically configure components using presets.

  4. The Repeater only has one property called Data array. Mouse over that property to reveal the data binding icon to the right and click it.

  5. This brings up the new visual data binding feature introduced in the Washington DC release. This shows you all of the data that is available for you to bind or connect to your components. Choose Data resource > look_up_notes > results and either double-click results, drag it up, or click the arrow to bind the data. Make sure that the data binding has moved up to the blank area at the top!

    This new data UI for Washington DC presents data and formulas in a more visual way. You can now create complex data binding values that combine both data output, script output, client state parameters, and formulas.

  6. Click Apply. You should now see the data binding in the Data array property.

  7. Now click on the Styles next to the configuration tab of the repeater component and choose Enable styles. Enabling styles for the repeater effectively turns it into a container which can be useful in certain cases to reduce the number of elements on your page.

  8. Fill in the Styles panel as follows:

    • Type: Grid

    • Columns: 5

    • Rows: 1

    • Gap: L

  9. Save the page in UIB.

    We are leveraging CSS Grid to layout this part of the page. CSS Grid (learn more about CSS Grid on MDN) is a really useful web standards-based layout system for when you have a variable number of items that will be returned from the database. You setup the rules of the grid (in this case 5 columns with a large gap) and the web browser will keep increasing the number of rows required for the data that you give it, no matter if your array has 20 items or 200 items.

Add components to the repeater​

You've bound data to and styled the repeater, but you'll need to add additional components to see the data reflected on the page.

  1. Inside the repeater, add a Card Base Container.

  2. Choose None for the presets.

  3. Set the Interaction property to Click on the config panel.

  4. Add a Heading component inside the Card Base Container.

  5. Choose None for the preset, and set the Style property to Header-tertiary.

  6. For the Label property, use the data binding icon to open the visual data binding modal.

  7. Choose Repeater > value > title > displayValue and choose Apply. Any components that are inside a repeater will have the option to leverage the repeater data array.

    You'll now see an actual note title displayed in the preview

    You'll notice that the data binding is contextually aware. Since this component is inside a repeater you have access to the values that you bound to the repeater from the data resource.

  8. Add a Highlighted value component after the Heading component by right-clicking Heading 2 in the content tree and choosing Add after.

  9. Choose None for the preset and configure the component as follows using data binding:

    • Label: <data binding> Repeater > value > category > displayValue

    • Color: <data binding> Repeater > value > category > _reference > color > displayValue

  10. Now add a Label value component after the Highlighted value component by right-clicking in the content tree and choosing Add after.

  11. Choose None for the preset and configure the component as follows:

    • Label: Created:

    • Value: <data binding> Repeater > value > sys_created_on > displayValue

  12. Click into the Styles tab of the Label value component and set the Margin-top to S.

  13. Save the page and click the Preview button next to Save to test the page.

    You should see cards with all the notes and their values filled in.

Add Pagination​

Returning all 41 notes is probably too much data to display on the page, and over time that could grow pretty large and affect performance. One of our performance engineers has a great article about repeaters, pagination, and performance if you want to go deeper.

Set up client state parameters and data resources​

In this section, you'll add a few client state parameters. You can think of client state parameters as the page's scratchpad or as the page's state. You can populate them and then bind them to multiple components and manage the values on the component by updating the CSP.

  1. Click the Client state parameters button in the Data and scripts panel to open the editing modeless dialog window.

  2. In the Edit client state parameters dialog that comes up, edit the first CSP and add another using the +Add button. Set the Name, Type, and Initial values as follows:

    • noteLimit | number | 10 (This will limit the number of notes records returned at any time and the pagination component will allow you to change this limit, similarly to a standard ServiceNow list)

    • notePageOffset | number | 0 (This will control which page you're currently looking at. So for 42 record, page 2 would be 11-20)

  3. Close the Edit client state parameters dialog and add an Aggregation Query data resource using the plus sign when you mouse over the Data resources section.

    The aggregation data resource will give you the total number of available records in the most performant way possible. You'll use that number in the pagination component.

  4. Rename the data resource by clicking the (i) icon at the top of the configuration panel next to the name of the data resource:

    • Data resource label: Note count

    • Data resource ID: note_count

  5. Set the following properties

    • Table: Note [x_snc_killer_notes_note]

    • Edit conditions: User | is (dynamic) | Me

  6. Close the Note count data resource panel and open the Look up notes data resource by clicking its name in the Data resource section

  7. Scroll down and set the following for the Max results and Pagination offset properties using the data binding icon.

    • Max results: <data binding> Client states > noteLimit

    • Pagination offset: <data binding> Client states > notePageOffset

  8. Close the data resource panel and Save your page.

  9. You may run into some caching issues testing the page, so for this one, click the down arrow next to Preview and choose Open URL path. If you see more than 10 records still, do a hard refresh of your browser using CMD+SHIFT+R on mac or CTRL+F5 on windows, which clears the cache on the page as you refresh. You should now see 10 cards/records.

Pagination controls component​

Now you'll need to add the pagination component and configure it to set the pagination Client State Parameters based on clicks.

  1. Add a Pagination control component after the repeater (right-click on the repeater component in the content tree). Make sure this component is placed outside the repeater or you'll get unexpected results.

  2. Choose None for the preset and configure the component as follows:

    • Total records: <data binding> Data resource > note_count > output > data > GlideAggregate_Query > 0 > count

    • Viewable items per page: <data binding> Client states > noteLimit

  3. Select the Events tab, choose +Add event mapping, and choose Pagination control selected page set (the first event).

  4. Choose Update client state parameter and set the Client State Parameter Name to notePageOffset.

  5. Select the data binding option for New Value to bring up the dynamic data binding option. You're going to use a simple formula to multiply two numbers together. Click the Formulas tab, choose Math, and choose Multiply.

  6. Now you'll need to populate the left and right values with data. Left should already be highlighted but click back into it if not. Click the Data types tab and choose Event payload > value. If you have trouble getting the value up there, select the part of the formula you want to insert into first, and then double-click to add. You can also drag and drop data values and formulas, which can be easier.

  7. Now for the right side, click into it and choose Client states > noteLimit.

  8. Click Apply and then Add for the event handler.

    With that step you're having the pagination component tell the look up notes data resource which page it needs to return. So if you click on page 3, it returns items 21-30 if you're returning 10 items per page.

  9. Now add a new event mapping and choose Pagination control selected page size set.

  10. Add the Update client state parameter event handler to the new event and set:

    • Client State Parameter Name: noteLimit

    • New Value: <data binding> Event payload > value (you may need to drag the value up to the Add a data output... area)

  11. Click Apply and then Add for the event handler.

  12. Save the page and test the pagination by going to your new tab and doing a hard refresh. Try paging to the next page and watch the notes change. Try changing the record per page to 20 and watch the page respond.

You now have a page that pulls and displays notes with pagination controls.

Back to classic button​

In this section, you'll add a button to the page footer that will only display for admins. The button will open the Notes table in the classic UI in a new browser tab so admins can easily troubleshoot, etc.

Add the button​

  1. In your UI Builder tab, scroll down to the Footer Container in the content tree and add a Button bare component.

  2. Choose None for the preset and set the following properties:

    • Label: Go to the notes table in classic

    • Icon (the second one): arrow-up-right-outline

  3. Switch to the Events tab and add an event handler to the Button bare clicked event.

  4. Choose Link to destination and then choose Select destination.

  5. Choose External URL and set it to: now/nav/ui/classic/params/target/x_snc_killer_notes_note_list.do

  6. Click OK and then Add.

  7. Save the page and test by opening the url path next to Preview. When you click the button it should open the notes list in a new tab.

Hide the button for non-admins​

In UI Builder, you can get the list of roles for the logged-in user. You're going to check and see if the admin role is one of those roles and if not, hide the footer container.

  1. Back in UIB, click on the Footer Container in the content tree.

  2. Click on the Configure tab in the right panel.

  3. Click Component Visibility, mouse over the Hide component property, and choose the data binding icon to launch the data binding modal.

  4. Click on the Formulas tab, click Comparison, and choose NOT.

  5. Next with the operand highlighted, click String, then INCLUDES.

  6. Now with stringOrArray highlighted click back into Data types and choose Page properties > session > user > roles.

  7. Now double click into value and type "admin" (with the quotes, you're telling it it's a string and not dynamic) At this point, you've built a formula that says "The logged-in user's roles do not contain the admin role."

  8. Click Apply and Save the page.

  9. Test the page in a new window as the admin user and the button should appear. Try impersonating Abel Tuter (you may need to click Open URL path again in UIB) Does the button show up?

  10. End the impersonation.