---
title: "Portal Data Tables"
slug: "portal-tables"
updated: 2025-04-01T21:50:08Z
published: 2025-04-01T21:50:08Z
---

> ## Documentation Index
> Fetch the complete documentation index at: https://knowledge.technolutions.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Portal Data Tables

**Data tables**in portals let users intuitively interact with data you pull from a query.

[![mceclip0__14_.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/1h6p3xvbbkcnrpu7lmxjpqmceclip0__14_.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/1h6p3xvbbkcnrpu7lmxjpqmceclip0__14_.png)

## Before you begin

This article covers two methods of creating tables in portals: the **table widget** and **liquid looping.**

- **Option 1: Table widget:**More straightforward and user-friendly, but limited to one table per view
- **Option 2: Liquid looping:**Provides additional options for more advanced users, including multiple tables per view

Regardless of the method you use, you must create a **query** to return data.

#### One-to-many data

Data tables in portals usually display data with a **one-to-many**relationship.

For example, a single applicant likely has multiple test scores to be displayed on their status portal, or one alumni volunteer might be assigned multiple interviewees.

**📖 Further reading:**[The one-to-many relationship](/v1/docs/joins)

#### Portal-building prerequisites

Before you try to add data tables to a portal, you should be familiar with the following prerequisite materials:

- [Creating a Custom Portal](/v1/docs/creating-a-custom-portal)
- [Liquid Markup Looping](/v1/docs/liquid-markup-looping)
- Basic HTML, particularly the `table`, `tr`, and `td` tags

## **Creating the portal query**

First, we need to create a query:

> [!NOTE]
> 1. Go to **Database → Portals.**
> 2. Select an existing portal, or [create a new one](/v1/docs/creating-a-custom-portal).
> 3. Create a new query in your portal.
> 4. Select **Edit Parameters.**
> 5. In the **Output Node**field, enter a name for the node.
> 
> [![blobid0__2_.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid0__2_.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid0__2_.png)
> 6. Select **Save.**

In this example, the query returns a list of prospects. The results set from the query is then placed into the node `person_list`.

**📖 Further reading:** [Output nodes](/docs/creating-a-custom-portal#output-nodes)

> [!TIP]
> **✨ Tip:**Include a sort to set the order in which the results should appear.

## Option 1: Table widget

In a portal **view**, select a **Table View widget** from the palette.

The widget contains four areas of configuration:

- **General settings:**For configuring the table view
- **Page Display:**To determine how the widget should render in the portal view
- **Table Layout:**For formatting table contents
- **Filters:**To filter the results returned by the query

> [!WARNING]
> 📝 **Note:**Views can only include one table widget; use [Liquid Looping](/v1/docs/portal-tables#liquid-looping-method) if you need to display multiple tables in a view.

#### General settings

Configure the following settings:

- **Name:**Give the table a name
- **Status:**Active
- **CSS Class Name:** See [Additional customization with CSS classes](/v1/docs/portal-tables#additional-customization-via-css-classes)
- **Query:**Select the query you created earlier to populate the table results. Only portal queries with an output node appear in the list.
- **Items per page:**Enter a number to limit the table’s pagination to that many rows. If left blank, defaults to 50.
- **Generate Code:**Selecting **Generate Template**adds the table, as well as the basics of the Liquid markup and looping. These can be edited after generation.

[![blobid3.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid3.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid3.png)

#### Page display

When you select **Generate Template,** the Page Display field is populated with:

- Header text (a centered `h2`)
- Liquid markup that displays the table if the size of the node is greater than 0, and a generic error message if not (that is, if no results are returned).

[![blobid4.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid4.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid4.png)

Select **Source.**

In the source code, you’ll notice that JavaScript has been generated automatically that renders the table on the portal view:

[![blobid5.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid5.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid5.png)

#### Table layout

Moving on to **Table Layout**, you’ll find a table is generated that uses the names of the exports in the query as column headers.

Table Layout also shows the Liquid markup generated that conditionally displays the *Prev* and *Next* links based on your specified number of results. The conditional aspect comes into play when there are no additional results before or after the current page.

[![blobid6.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid6.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid6.png)

Here, you can also see the Liquid looping syntax by selecting **Source**.

- The table includes all exports from the portal query.
- The merge fields reflect the order of the exports in the query.
- The columns can be edited or removed as desired.

[![blobid7.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid7.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid7.png)

The end result in this example:

[![mceclip0__14_.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/1h6p3xvbbkcnrpu7lmxjpqmceclip0__14_.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/1h6p3xvbbkcnrpu7lmxjpqmceclip0__14_.png)

### Editing the table

If, after testing, you wish to make any changes to the table, or if additional exports were added to the query and you would like those new exports included in the table, the table template can be reset by editing the table and clicking "Reset Template." Alternatively, the table can also be directly edited in the Table Layout to add the new exports.

[![blobid9.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid9.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid9.png)

### **Adding pop-ups**

**Portal pop-up**functionality displays additional information about a particular row in the results list.

📖 **Further reading:**[Portal pop-ups](/v1/docs/portal-pop-ups)

When using the table view widget, a link to a pop-up is automatically generated within the table if the query used contains the exports of `id` and `name`.

- Specifically, both `id` and `name` are referenced in the same table cell, and the link is associated with a portal pop-up method that has an Action of `details`.
- When the table is rendered on a portal page, each table row can then display a pop-up when the user selects anywhere on that row.
- If the method in the portal has a different *Action*, the source code can be edited to match the desired method.

[![blobid8.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid8.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/blobid8.png)

```xml
<td>
    <a data-href="?cmd=details&amp;id={{item.id}}" href="#" onclick="return (FW.Lazy.Popup(this, {width: '500px'}));">
        {{item.name}}
    </a>
</td>
```

> [!WARNING]
> 🙈 Don’t see the pop-up links?
> 
> Only portal queries that have **exports**with the labels `id` and `name`****will generate this link. In a Configurable Joins query, these exports will default to the names *Person GUID*and *Person Name*, respectively. If these two exports are not added to your query, or do not have the correct labels, the link must be added manually.

## **Option 2: Liquid looping**

Using Liquid looping, you can add multiple data tables to the same portal view.

### Creating the method

> [!NOTE]
> 1. Select **New Method**.
> 2. Configure the following settings:
>   - **Status**: Active
>   - **Name**: Provide a descriptive name, such as *Test Score Table*.
>   - **Type**: GET
>   - **View**: Application Status Page
>   - **Output Type**: Default Branding
> 3. Select **Save**.
> 4. Select **Create New Query**.
> 5. Configure the following settings:
>   - **Name**: Provide a descriptive name, such as *Test Scores*.
>   - **Population**: The query base should be the item to be displayed. For this example, select the *Test Scores* query base to pull one row per test score.
> 6. Add the **exports**to be used as merge fields in the Portal View. We recommend updating the export label to be lowercase and use underscores instead of spaces.
> 7. Add the following filters:
>   - **Test Status**: Include the *Test Status*to display verified test scores received.
>   - **Portal Identity**: When using a query base that is not *Applications*for the Applicant Status Portal, the *Portal Identity*filter must be adjusted. In this case, the `[record]` on `[test]` is the `[person]` on the `[application]` table. The filter has been updated to make the appropriate connections.
> 
> [![data_table_sql_filter.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/data_table_sql_filter.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/data_table_sql_filter.png)
> 8. Select **Edit Parameters**.
> 9. In the **Output Node****field, enter a value. For example, if displaying a list of test scores, call the node `test_scores`.

### **Adding merge fields to the view**

To add the merge fields to the portal view using Liquid looping:

> [!NOTE]
> 1. Select the appropriate view.
> 2. Add a static content block from the portal builder palette.
> 3. Build a table with columns for the different data points to be displayed. In the Source code, add in Liquid markup to loop through the results, as in the following example. Note how the Liquid markup refers to the node of the portal query, and each merge field is prefixed with `result`:
> 
> ```xml
> <tbody>
>     {% for result in test_scores %}
>         <tr>
>             <td>{{result.test_date}}</td>
>             <td>{{result.test_type}}</td>
>             <td>{{result.test_total}}</td>
>         </tr>
>     {%endfor%}
> </tbody>
> ```

If only displaying verified test scores, use the *Has Verified Test Score* filter to show this table to applicants with verified test scores to display.

[![part.png](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/part.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/part.png)

## Additional customization via CSS classes

When creating tables using HTML in portals, various table classes and table row classes can be leveraged to allow for a variety of functionality and design aesthetics.

Classes can be either predefined within Slate, like the following table classes, or they can be custom, such as creating custom classes specific to your institution. When an HTML element is given a Slate predefined class, a class defined in your branding, or a custom class defined in your portal, that attribute will inherit the style of the specified class.

### **Table Classes**

Table classes can be used to adjust the display and functionality of a table.

#### `sortable`

If the headers in a table should allow the portal user to sort the data displayed, a class of `sortable` can be used.

If the table is leveraging the [Table View Widget](/v1/docs/portal-table-view-widget), the headers will only sort the data appearing on that page of table. It will not sort all paginated results.

```xml
<table class ="table sortable">
```

[![Sortable Table Headers](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/pyhjvdlg8uebjebgitw6bwmceclip0.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/pyhjvdlg8uebjebgitw6bwmceclip0.png)

[![Source Code for Sortable TAble Class](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/iqyeumzzue4rjmpsxexvwmceclip1.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/iqyeumzzue4rjmpsxexvwmceclip1.png)

  

#### `searchable`**and**`data-search-text`

The table class `searchable` adds a search bar to the table, allowing portal users to search any text appearing within the table.

[![Searchable Table Class](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/yja06og7cuixoun9wzyamceclip2.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/yja06og7cuixoun9wzyamceclip2.png)

`data-search-text` can also be added to display instructions or additional information in the search box.

```xml
<table class="table searchable" data-search-text="Search Records...">
```

#### `nohighlight`

Typically, if a column in a table row is a link, the entire row becomes a link, letting the portal user click anywhere on the row to open the link.

However, you may want the user to be able to select just one column. The table class `nohighlight` lets users select only those columns with links.

```xml
<table class="table nohighlight">
```

[![Nohighlight Table Class](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/97esyjjq0kmusgkzgzxpoamceclip0.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/97esyjjq0kmusgkzgzxpoamceclip0.png)

In this example, only the second column is a link, rather than the entire table row.

#### Combining classes

These table classes can be combined to create a table that is both `sortable` and `searchable`, `sortable` and `nohighlight`, or all three.

```xml
<table class="table sortable searchable nohighlight">
```

### **Table row classes**

**Table row classes**adjust the display of specific table rows.

Using Liquid markup, certain rows can be displayed differently based on certain criteria. For example, in a table of applicants, the portal user may wish to see admits highlighted in green and denied applicants highlighted in red.

[![Table with Different Table Row Classes](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/wkramfetzk6c3ugjxlqewmceclip1.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/wkramfetzk6c3ugjxlqewmceclip1.png)

#### **Creating the table row classes**

In order to conditionally change the display of a table row, different table row classes must be set. Use `&lt;style&gt;` tags set background color or other properties.

In the following example, a `&lt;tr&gt;` with class `admit` receives a green background. Rows with the class `deny` receive a red background. A merge field determines the class.

```xml
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <style type="text/css">
        /*<![CDATA[*/
        tr.Admit {background-color: green; }
        tr.Deny {background-color: red; }/*]]>*/
    </style>
</head>
<body>
    <table class="table searchable sortable nohighlight">
        <colgroup>
            <col />
            <col />
            <col />
        </colgroup>
        <thead>
            <tr class="column">
                <th>Person Name</th>
                <th>Person Major</th>
                <th>Person Decision</th>
            </tr>
        </thead>
        <tbody>
            {% for item in applications %}
                <tr class="{{item.decision}}">
                    <td>{{item.name}}</td>
                    <td><a href="LINK HERE" target="_blank">{{item.major}}</a></td>
                    <td>{{item.decision}}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>
```

#### **Adding the query export to be used as a table row class merge field**

As referenced earlier, a merge field is used to set the class. This merge field must be an export in the associated query.

In this example, the merge field is `{{item.decision}}`, where `item` is the [Liquid looping prefix](/v1/docs/display-data-tables-in-a-portal), as determined by `{% for item in applications %}`, and `decision` is the export label in the query.

[![Query Export Used in Table Row Class](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/4cjwodnpyuspmvztxahx3wmceclip2.png)](https://cdn.us.document360.io/cd8ea7a6-07f3-4846-a554-627ac016d3e3/Images/Documentation/4cjwodnpyuspmvztxahx3wmceclip2.png)

## Related

- [The For Tag and Liquid Looping](/liquid-markup-looping.md)
