---
category: [Administration & Integrations, Platform and Product Extensions, Platform and Product Extensions/Integration, Administration & Integrations/Custom Integrations & Apps, Platform and Product Extensions/Workday Extend]
keyword: [Extend, Presentation Components, UI components]
nav: wcp_docs
parent_url: /wcp_docs/
title: >- 
  Concept: Displaying Data
layout: subsection
---

## <a id="section_bindingData"></a>Displaying Data from Inbound Endpoints

Inbound endpoints are REST APIs that return JSON data that the widgets display or evaluate when the page loads. Define inbound endpoints in the `endPoints[]` section of a PMD. When you define an inbound endpoint, specify its URL, authentication type, and name. The endpoint name enables you to reference its data when you bind its fields to tag attributes.

<b>Note:</b> Presentation Components call all inbound endpoints on the PMD upon loading the page. To improve the page load performance, ensure that all endpoints are performant and use appropriate filter and paging parameters. You can use the `exclude` attribute of an endpoint to exclude it from invocation if a condition might return an error.

<b>Note:</b> Presentation Components impose a 24-second timeout on each endpoint. Individual endpoints exceeding the 24-second limit return a timeout error. In addition to the endpoint limit, Presentation Components also impose a 60-second timeout on a request. A request can include initial page loads, page submissions, and remote validations. (A single request can call multiple endpoints.) All of these operations must complete within 60 seconds; otherwise the page returns a timeout error. This measure protects the Workday tenant from poor performance. To avoid the request timeout, consider limiting the number of endpoints and ensure that you call performant endpoints on each page.

To display data from the inbound endpoint, bind a field with its JSON path using this expression:

```
<% inboundEndpointName.fieldPath %>
```

This sample inbound endpoint, named `worker`, specifies the `GET /workers` REST API with the path parameter `me`:

```
"endPoints": [
    {
      "name": "worker",
      "baseUrlType": "workday-staffing",
      "url": "/workers/me",
      "authType" : "sso"
    }
]
```

The sample `worker` endpoint returns this JSON data snippet:

```
{
  "data": [
    {
      "descriptor": "Logan McNeil",
      "id": "3aa5550b7fe348b98d7b5741afc65534",
      "person": {
        "email": "lmcneil@workday.net",
        "id": "9feb1da3167840a9852698a2f228f795",
        "phone": "+1415789-8904"
      },
      . . .
    }
  ],
  "total": 1
}
```

Assume you want to display the worker name and email contact on the `label` and `value` attributes of a `text` tag. Specify the `descriptor` and `person.email` fields as binding expressions on the corresponding attributes. Example:

```
{
  "type": "text",
  "id": "workerNameAndEmail",
  "label": "<% 'Email Address of' +  worker.descriptor %>:",
  "value": "<% worker.person.email %>"
}
```

When the page loads, Presentation Components resolve the values of tag attributes that have a binding data type. To determine whether a tag attribute has a binding data type, see its tag attribute description in [Reference: PMD Tags](/wcp_docs/dyg1528862158582.html). The binding data types use 1 of these prefixes:

-   `binding`

    A tag attribute with a `binding` data type resolves its value only upon initial page load. The attribute value won't change with user interactions on the page.

-   `dynamicBinding`

    A tag attribute with a `dynamicBinding` data type resolves its value upon initial load of an edit page. After the page has loaded, the dynamic attribute value can also change with user interactions.



## <a id="section-dynamically-displaying-data-during-page-interactions"></a>Dynamically Displaying Data during Page Interactions

With dynamic binding, you can set some attributes of a tag based on the data or how the user interacts with data on another widget. You can dynamically bind data only on tag attributes with `dynamicBinding` data type, and only on edit pages. Common tag attributes that support dynamic binding are `enabled`, `label`, `required`, `value`, and `visible`.

This sample `text` tag is visible only if the endpoint data is empty:

```
{
  "type": "text",
  "id": "noCharitiesMessage",
  "value": "There are no Charities available for donation at this time.",
  "visible": "<% empty(charities.data) %>"
}
```

<b>Note:</b> If a widget is not visible on an edit page (when the `visible` attribute is false), the outbound endpoint doesn't include the widget's `valueOutBinding` or `valuesOut` data in the outbound payload. To include the outbound data from an invisible widget, use the `onSend` event handler.

In this next example, the `section` tag isn't visible when the page loads. It only becomes visible after the user selects a value from an `instanceList`:

```
{
  "type": "section",
  "id": "workerDetail",
  "visible": false,
  "columnWidthRatios": [
    0.3,
    0.7
  ],
  "horizontal": true,
  "children": [
    {
      "type": "section",
      "children": [
      {
        "type": "readOnlyText",
        "id": "descriptor",
        "label": "Full Name"
      },
      . . .
      ]
    },
    {
      "type": "section",
      "children": [
      {
        "type": "readOnlyText",
        "id": "dateOfBirth",
        "label": "Date of Birth"
      },
      . . .
      ]
    }
  ]
}
```

When a user selects a worker from this `instanceList`, the `onChange` event handler populates and sets the `workerDetail` section to visible.

```
{
  "type": "instanceList",
  "id": "instanceListWorkerSearch",
  "label": "Worker",
  "values": "<% workers.data %>",
  "multiSelect": false,
  "onChange": "<% populate(self.value); %>"
}
```

This snippet contains the `populate` function, which invokes the `getWorkerbyId` endpoint to get the worker information. It then sets `workerDetail.visible` to `true` to display the `workerDetail` section with the worker information.

```
"script": "<%
    // Invoke endpoint and pass id as a URL paramater
    var populate = function(id) {
      if( !(empty id)) {
        var workerData = getWorkerbyId.invoke({'id': id[0]});
        descriptor.value = workerData.descriptor;
        dateOfBirth.value = workerData.dateOfBirth;
        workerDetail.visible = true;
      } else {
        workerDetail.visible = false;
      }
    };
%>"
```

## <a id="section_dataCollection"></a>Displaying a Data Collection

A data collection from an endpoint contains a list of records and the total number of records. A data collection from a Workday REST API contains the `data[]` list and the `total` field. A record in the list contains an object instance identified by the `id` field and described by the `descriptor` field. A `workers` endpoint returns this sample data collection:

```
{
  "data": [
    {
      "descriptor": "Logan McNeil",
      "id": "3aa5550b7fe348b98d7b5741afc65534",
      "person": {
        "email": "lmcneil@workday.net",
        "id": "9feb1da3167840a9852698a2f228f795",
        "phone": "+1415789-8904"
      },
      . . .
      }
    },
    {
      "descriptor": "Lotte Bakker",
      "id": "7cb015b801014816bff5929311807ca1",
      "person": {
        "email": "lbakker@workday.net",
        "id": "231ca0391fef406ea952e45df2f60a9e",
        "phone": "+31020537 1922"
      },
      . . .
      }
    }
  ],
  "total": 2
}
```

To display a data collection, you can use either of these types of widgets:

-   <b>List</b>

    Displays the data collection as a list of selection values. Different list tags provide different ways to visualize and interact with a list, such as `checkBoxList`, `dropdown`, `dropDownButton`, `instanceList`, and `panelList`.

    In general, these list widgets require that the inbound list contains the `id` and `descriptor` fields. By default, the list widgets display the `descriptor` values on the list, and use the `id` to identify the values. You can override the `id` and `descriptor` fields by specifying the `idKey` and `displayKey` attributes.

    To bind the list of `values`, specify `<% inboundEndpointName.data %>`, where `data` is the name of the list array. Example: `<% workers.data %>`.

    To bind a specific instance in the list, use an index number. Example: `<% workers.data[0] %>` is the first instance in the list.

    This sample `instanceList` displays the `descriptor` fields from the `workers` endpoint:

    ```
    {
       "type": "instanceList",
       "label": "Simple instanceList",
       "id": "instanceListSimple",
       "values": "<% workers.data %>"
    }
    ```

    For details about how to use each type of list widget, see its tag documentation in [Reference: PMD Tags](/wcp_docs/dyg1528862158582.html).

-   <b>Grid</b>

    Displays the data collection as rows and columns of data. Use the `grid` tag along with the `column`, and `cellTemplate` tags to define a grid.

    To bind the data to the grid `rows`, specify `<% inboundEndpointName.data %>`, where `data` is the name of the list array.

    To bind a field to each cellTemplate `value`, specify `<% rowVariable.fieldPath %>`, where `rowVariable` is the `rowVariableName` attribute of the grid, and `fieldPath` is the path to the field in the JSON list.

    This sample `grid` displays the `descriptor` and `person.email` fields from the `workers` endpoint:

    ```
    {
      "type": "grid",
      "label": "Simple grid",
      "id": "gridSimple",
      "rows": "<% workers.data %>",
      "rowVariableName": "thisRow",
      "columns": [
        {
          "type": "column",
          "columnId": "col1",
          "label": "Worker",
          "cellTemplate": {
            "type": "text",
            "value": "<% thisRow.descriptor %>"
          }
        },
        {
          "type": "column",
          "columnId": "col2",
          "label": "Email address",
          "cellTemplate": {
            "type": "text",
            "value": "<% thisRow.person.email %>"
          }
        }
      ]
    }
    ```

    If you're displaying a value from a multi-instance field in a grid, treat the multi-instance field as a list by specifying the list index. Example: This text widget displays the descriptor field of the first row from a multi-instance field:

    ```
    {
      "type": "column",
      "label": "Descriptor",
      "columnId": "descriptorColumn",
      "cellTemplate": {
        "type": "text",
        "id": "multiInstanceField",
        "enabled": false,
        "value": "<% myData.myMultiInstanceField[0].descriptor ?? '' %>"
      }
    }
    ```

    For details about how to use the `grid` widget, see the [grid](/wcp_docs/zmz1518211268000.html) tag documentation.

-   <b>Loop</b>

    Displays the data collection as a repeated set of widgets. Use the loop tag with a `children` array of widgets that display fields from each record in the list.

    To bind the list `on` the loop, specify `<% inboundEndpointName.data %>`, where `data` is the name of the list array.

    To bind a field to each widget `value` in the set, specify `<% asVariable.fieldPath %>`. `asVariable` is the `as` attribute of the loop, and `fieldPath` is the path to the field in the JSON list.

    This sample `loop` displays the `descriptor`, `person.email`, and `person.phone` fields from the `workers` endpoint:

    ```
    {
      "type": "loop",
      "on": "<% workers.data %>",
      "as": "loopData",
      "children": [
        {
          "type": "fieldSet",
          "collapsible": "true",
          "initializeCollapsed": "true",
          "title": "<% loopData.descriptor %>",
          "children": [
            {
              "type": "text",
              "label": "Email address:",
              "value": "<% loopData.person.email %>"
            },
            {
              "type": "text",
              "label": "Phone:",
              "value": "<% loopData.person.phone %>"
            }
          ]
        }
      ]
    }
    ```



## <a id="section_deferredData"></a>Displaying Deferred Data

In some cases, you might need to fetch and display data on a widget only after a user selected a value on another widget. You can defer calling the endpoint that displays the dependent data until the user has made a selection.

The sample `onChange` event handler in [Dynamically Displaying Data during Page Interactions](/wcp_docs/qau1572291138966.html#section-dynamically-displaying-data-during-page-interactions) demonstrates the invocation of an endpoint only when the user selects a value from an `instanceList`.

For details about how to invoke deferred endpoints with PMD Scripting, see Invoking Endpoints in [Concept: PMD Scripting](/wcp_docs/oli1581402304020.html).

## <a id="section_manipulateData"></a>Manipulating Data Display with Scripts

You can use PMD Scripting to manipulate widget values. Presentation Components provide PMD functions for parsing and manipulating the data from an endpoint before displaying it on a widget. The PMD functions belong to namespaces that pertain to the type of object they apply to. Examples: `string`, `list`, `number`, `date`, `json` contain related PMD functions.

In this example, a `dropdown` widget provides an option to display sorted data in a `grid`. The `dropdown` widget calls an `onChange` event handler, <i>changeGridSource</i>.

```
{
  "type": "dropdown",
  "id": "dataList",
  "onChange": "<% changeGridSource(self.value); %>",
  "instanceList": [
    . . .,
    {
      "id": "4",
      "descriptor": "Custom Sorting"
    },
    . . .
  ]
}
```

The <i>changeGridSource</i> event handler processes each list option. When the user selects the custom sorting option, it calls the <i>sortList</i> script to set the rows of the sample `dataGrid`.

```
var changeGridSource = function(option) {
  if (option.isEmpty()) {
    dataGrid.setRows(emptyList());
  } else {
    . . .
    if (option[0] == '4') {
      dataGrid.setRows(sortList());
    . . .
    }
  }
};
```

The <i>sortList</i> script first calls the `sort` list function to sort the business titles from the endpoint data. Then it calls the `map` list function for the output rows with <i>column1</i> and <i>column2</i> values.

```
// Sort list by businessTitle, then map two columns (businessTitle, descriptor).
var sortList = function() {
 return workers.data
  .sort(worker => { worker.businessTitle })
  .map( worker => {
   {
     'column1': worker.businessTitle,
     'column2': worker.descriptor
   }
 });
};
```

The output of <i>sortList</i> script populates the rows on this sample `dataGrid`:

```
{
  "type": "grid",
  "id": "dataGrid",
  "rows": "<% emptyList() %>",
  "rowVariableName": "row",
  "doNotAdd": "true",
  "doNotRemoveRow": "true",
  "enabled": false,
  "columns": [
    {
      "type": "column",
      "columnId": "column1",
      "label": "Column 1",
      "cellTemplate": {
        "type": "text",
        "value": "<% row.column1 %>"
      }
    },
    {
      "type": "column",
      "columnId": "column2",
      "label": "Column 2",
      "cellTemplate": {
        "type": "text",
        "value": "<% row.column2 %>"
      }
    }
  ]
}
```

### Related Information

[Concept: PMD Scripting](/wcp_docs/oli1581402304020.html)

[Concept: Displaying Widgets](/wcp_docs/oqk1573076553441.html)

[Concept: Submitting Data](/wcp_docs/rmd1572291186381.html)

[App Catalog: Charitable Donations](/app-catalog/charitableDonations)

[App Catalog: PMD Scripting](/app-catalog/pmdScripting)

