Data table and Iframe card interaction

A layout template includes a data table card and an Iframe card. It is possible for the Iframe card to update its query parameters depending on which row is selected.

To enable the feature, certain configurations are needed for the data table and iframe card.

Configurations for the data table


{
  "name": "enablePersistRowData",
  "values": ["true"],
  "metaInformation": "tableOption"
},
{
  "name": "persistRowDataScope",
  "values": [""], // optional, the scope we'll save it under in state, default is `selectedRowData`
  "metaInformation": "tableOption"
}

This option persists the id of the clicked row to subscribable.$shared.selectedRowData, or a value other than selectedRowData can be specified, in your store. For this option to work, you need an id for every row, which needs to be set in the transformation.

To clear the state when the card is destroyed:

{
  "name": "widgetDestroyed",
  "values": ["clearStates"],
   "metaInformation": "eventSubscription"
},
{
  "name": "clearStates",
  "values": ["iframeQueryParam"], // this should be the name of the scope you want to clear.
  "metaInformation": "eventPayload"
}

It is stored in state in the following structure:


{
  subscribable: {
    $shared: {
     selectedRowData: { // could be something other than persistedRowData if specified
        id: '',
        rowData: {} // the values in the row
      }
    }
  }
}

Configurations for the Iframe card


{
  "name": "iframe.baseUrl",
  "values": ["UIHub"],
  "metaInformation": "widgetOption"
},
{
  "name": "iframe.path",
  "values": [""], // eg value: `/template/DEFAULT_INVENTORY_DETAIL_LAYOUT_TEMPLATE`
  "metaInformation": "widgetOption"
},
{
  "name": "iframe.queryParams",
  "values": [""], // eg value: `inventoryId={{ iframeQueryParam.id }}&hiddenLayoutSections=queue`
  "metaInformation": "widgetOption"
},
{
  "name": "iframe.token",
  "values": ["{{ token.raw }}"],
  "metaInformation": "widgetOption"
},
{
  "name": "iframe.cuiToken",
  "values": ["{{ cuiToken }}"],
  "metaInformation": "widgetOption"
},
{
  "name": "iframe.tenantId",
  "values": ["{{ tenantId }}"],
  "metaInformation": "widgetOption"
},
{
  "name": "iframe.offeringId",
  "values": ["{{ offeringId }}"],
  "metaInformation": "widgetOption"
},
{
  "name": "iframe.viewData",
  "values": ["{{ viewData }}"],
  "metaInformation": "widgetOption"
},
{
  "name": "token",
  "values": ["refreshOptions"],
  "metaInformation": "stateSubscription"
},
{
  "name": "cuiToken",
  "values": ["refreshOptions"],
  "metaInformation": "stateSubscription"
},
{
  "name": "iframeQueryParam", // this is the value we store in state when we click on a row, has to match the scope set in data table WD
  "values": ["refreshOptions"], // we refresh the iframe every time that value changes
  "metaInformation": "stateSubscription"
}
Behavior
Clicking any row within the data table updates the query parameter that is passed to the Iframe widget.

Data table with Iframe card

Data table: Out of stock inventory
Clicking a row saves the Inventory object information under iframeQueryParam in the state. The ID can be accessed with iframeQueryParam.id and any other attribute that is under iframeQueryParam.rowData.

{
    "offeringId": "SCO",
    "id": "DATA_IFRAME_POC_TABLE",
    "state": "ACTIVE",
    "identifier": "DATA_IFRAME_POC_TABLE",
    "type": "Dashboard",
    "tenantId": "<TENANT_ID>",
    "createdDate": "2022-08-18T16:13:17.318Z",
    "createdBy": "samsmith@ibm.com",
    "lastModifiedDate": "2022-08-23T14:41:52.881Z",
    "lastModifiedBy": "samsmith@ibm.com",
    "path": "/api",
    "vendor": "IBM",
    "defaultLanguage": "en",
    "version": 1,
    "description": {
        "name": "Out of stock inventory - updaed -1",
        "language": "en",
        "description": "View out of stock inventory"
    },
    "devConfigurations": [
        {
            "name": "header.path",
            "values": [
                "/template/INVENTORY_OUT_OF_STOCK_VIEW_ALL_LAYOUT_TEMPLATE"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "header.type",
            "values": [
                "metric_header"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "header.title",
            "values": [
                "COMMON.OUT_OF_STOCK_INVENTORY"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "header.tooltip",
            "values": [
                "COMMON.OVERVIEW_INVENTORY_OUT_OF_STOCK.TOOLTIP"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "header.value",
            "values": [
                "{{ totalCount }}"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "icons[0].type",
            "values": [
                "kebab_menu"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "icons[0].options[0]",
            "values": [
                "move"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "colSpan",
            "values": [
                "2"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "rowSpan",
            "values": [
                "22"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "data.service",
            "values": [
                "infohub"
            ]
        },
        {
            "name": "queries[0].processor",
            "values": [
                "EDGES"
            ],
            "metaInformation": "infohub.processor"
        },
        {
            "name": "queries[0].fields",
            "values": [
                "query OutOfStockInventory( $tenantId: String, $cursorId: String, $locationFilter: BooleanExp = { CONSTANT_VALUE: true }, $inventoryPlannerCoderFilter: BooleanExp = { CONSTANT_VALUE: true }, $categoryFilter: BooleanExp = { CONSTANT_VALUE: true }, $productStatusFilter: BooleanExp = { CONSTANT_VALUE: true }, $sortBy: String = \"product.name\", $sortOrder: SortOrder = ASC ) { OutOfStockInventory: businessObjects( advancedFilter: { AND: [ { LESS_EQUALS: [ { SELECT: \"quantity\", type: FLOAT }, { VALUE: \"0.0\", type: FLOAT } ] }, { EQUALS: [ { SELECT: \"inventoryType\", type: STRING}, {VALUE: \"PRODUCT\", type: STRING } ] }, $locationFilter, $inventoryPlannerCoderFilter, $categoryFilter, $productStatusFilter ] }, cursorParams: { after: $cursorId, first: 8, sort: { order: $sortOrder, fieldPath: $sortBy } }, hint: { viewId: \"graph\" }, simpleFilter: { tenantId: $tenantId, type: Inventory } ) { totalCount pageInfo { hasNextPage endCursor } edges { cursor object { ... on Inventory { id inventoryType plannerCode quantityBelowLowerThreshold inventoryParentType location { id locationIdentifier locationName locationType } product { id name status partNumber category { id name } } } } } } }"
            ],
            "metaInformation": "infohub.fields"
        },
        {
            "name": "queries[0].variables.tenantId",
            "values": [
                "{{ tenantId }}"
            ],
            "metaInformation": "infohub.variable.dynamic"
        },
        {
            "name": "queries[0].variables.cursorId",
            "values": [
                "{{ cursorId }}"
            ],
            "metaInformation": "infohub.variable.dynamic"
        },
        {
            "name": "queries[0].variables.locationFilter",
            "values": [
                "{ \"EQUALS_ANY\": [ {\"SELECT\": \"location.id\", \"type\": \"STRING\" }, { \"VALUES\": {{ inventory.appliedFilters.Location.ids }}, \"type\": \"STRING\" } ] }"
            ],
            "metaInformation": "infohub.variable.dynamicExpr"
        },
        {
            "name": "queries[0].variables.inventoryPlannerCodeFilter",
            "values": [
                "{ \"EQUALS_ANY\": [ {\"SELECT\": \"plannerCode\", \"type\": \"STRING\" }, { \"VALUES\": {{ inventory.appliedFilters.PlannerCode.ids }}, \"type\": \"STRING\" } ] }"
            ],
            "metaInformation": "infohub.variable.dynamicExpr"
        },
        {
            "name": "queries[0].variables.categoryFilter",
            "values": [
                "{ \"EQUALS_ANY\": [ {\"SELECT\": \"product.category.id\", \"type\": \"STRING\" }, { \"VALUES\": {{ inventory.appliedFilters.Category.ids }}, \"type\": \"STRING\" } ] }"
            ],
            "metaInformation": "infohub.variable.dynamicExpr"
        },
        {
            "name": "queries[0].variables.productStatusFilter",
            "values": [
                "{ \"EQUALS_ANY\": [ {\"SELECT\": \"product.status\", \"type\": \"STRING\" }, { \"VALUES\": {{ inventory.appliedFilters.ProductStatus.ids }}, \"type\": \"STRING\" } ] }"
            ],
            "metaInformation": "infohub.variable.dynamicExpr"
        },
        {
            "name": "queries[0].variables.sortBy",
            "values": [
                "{{ OutOfStockInventory.sort.by }}"
            ],
            "metaInformation": "infohub.variable.dynamic"
        },
        {
            "name": "queries[0].variables.sortOrder",
            "values": [
                "{{ OutOfStockInventory.sort.order }}"
            ],
            "metaInformation": "infohub.variable.dynamic"
        },
        {
            "name": "columnSorted",
            "values": [
                "OutOfStockInventory"
            ],
            "metaInformation": "stateScope"
        },
        {
            "name": "OutOfStockInventory.sort",
            "values": [
                "refreshData",
                "refreshSavedState"
            ],
            "metaInformation": "stateSubscription"
        },
        {
            "name": "inventory.appliedFilters",
            "values": [
                "refreshData"
            ],
            "metaInformation": "stateSubscription"
        },
        {
            "name": "draggable",
            "values": [
                "true"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "horizontalScroll.enable",
            "values": [
                "false"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "selectFirstRow",
            "values": [
                "true"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "enableRowSelect",
            "values": [
                "true"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "rowClicked",
            "values": [
                "drilldownRowData.row"
            ],
            "metaInformation": "stateScope"
        },
        {
            "name": "showFooter",
            "values": [
                "true"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "widget.footer.customTemplate",
            "values": [
                "linkTpl"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "widget.footer.label",
            "values": [
                "COMMON.VIEW_ALL"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "widget.footer.href.type",
            "values": [
                "LAYOUT_TEMPLATE"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "widget.footer.href.id",
            "values": [
                "INVENTORY_OUT_OF_STOCK_VIEW_ALL_LAYOUT_TEMPLATE"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "pagination.enable",
            "values": [
                "false"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "selectableRow.enable",
            "values": [
                "true"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "enablePersistRowData",
            "values": [
                "true"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "persistRowDataScope",
            "values": [
                "iframeQueryParam"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "stickyTableHeader",
            "values": [
                "false"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "stripes",
            "values": [
                "false"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "configurable",
            "values": [
                "false"
            ],
            "metaInformation": "tableOption"
        },
        {
            "name": "columns[0].cell.label",
            "values": [
                "{{ product.partNumber }}"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].header.label",
            "values": [
                "INVENTORY.PRODUCT.ID"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].sortable",
            "values": [
                "false"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].cell.customTemplate",
            "values": [
                "linkTpl"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].cell.href.type",
            "values": [
                "LAYOUT_TEMPLATE"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].cell.href.id",
            "values": [
                "DEFAULT_INVENTORY_DETAIL_LAYOUT_TEMPLATE"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].cell.href.params",
            "values": [
                "inventoryId={{ id }},hiddenLayoutSections=queue"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].hidden",
            "values": [
                "false"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[0].sequence",
            "values": [
                "0"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[1].cell.label",
            "values": [
                "{{ product.name }}"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[1].header.label",
            "values": [
                "INVENTORY.PRODUCT.NAME"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[1].sortable",
            "values": [
                "false"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[1].cell.customTemplate",
            "values": [
                "textTpl"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[1].hidden",
            "values": [
                "false"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[1].sequence",
            "values": [
                "1"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[2].cell.label",
            "values": [
                "{{ location.locationName }}"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[2].header.label",
            "values": [
                "COMMON.LOCATION"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[2].sortable",
            "values": [
                "true"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[2].cell.customTemplate",
            "values": [
                "textTpl"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[2].hidden",
            "values": [
                "false"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[2].sequence",
            "values": [
                "2"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[3].cell.label",
            "values": [
                "{{ quantityBelowLowerThreshold }}"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[3].header.label",
            "values": [
                "INVENTORY.LOW_QUANTITY"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[3].sortable",
            "values": [
                "false"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[3].cell.customTemplate",
            "values": [
                "numberTpl"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[3].hidden",
            "values": [
                "false"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "columns[3].sequence",
            "values": [
                "3"
            ],
            "metaInformation": "tableColumn"
        },
        {
            "name": "widgetDestroyed",
            "values": [
                "clearStates"
            ],
            "metaInformation": "eventSubscription"
        },
        {
            "name": "clearStates",
            "values": [
                "iframeQueryParam"
            ],
            "metaInformation": "eventPayload"
        },
        {
            "name": "widgetInitialized",
            "values": [
                "loadState",
                "refreshData"
            ],
            "metaInformation": "eventSubscription"
        },
        {
            "name": "transformation",
            "values": [
                "{ \"errors\": \"{{#? this.errors}}\", \"pageInfo\": \"{{this.data.OutOfStockInventory.pageInfo}}\", \"totalCount\": \"{{this.data.OutOfStockInventory.totalCount}}\", \"results\": { \"{{#each this.data.OutOfStockInventory.edges}}\": { \"cursor\": \"{{this.cursor}}\", \"id\": \"{{this.object.id}}\", \"quantityBelowLowerThreshold\": \"{{this.object.quantityBelowLowerThreshold}}\", \"location\": \"{{this.object.location}}\", \"product\": \"{{this.object.product}}\" } } }"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "state.empty.title",
            "values": [
                "COMMON.EMPTY_TITLE"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "state.empty.body",
            "values": [
                "COMMON.EMPTY_BODY"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "state.empty.link.label",
            "values": [
                "COMMON.EMPTY_LINK_LABEL"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "state.empty.link.href.type",
            "values": [
                "NEW_WINDOW"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "state.empty.link.href.path",
            "values": [
                "https://www.ibm.com/docs/en/sscis?topic=troubleshooting-no-data-display"
            ],
            "metaInformation": "widgetOption"
        }
    ],
    "userConfigurations": [
        {
            "name": "chartType",
            "values": [
                "data_table"
            ]
        }
    ],
    "adminConfigurations": []
}
Iframe widget: Showing inventory detail page
Only the ID is used but both the inventory ID and inventory.product.partNumber are passed.

{
    "id": "POC_IFRAME",
    "state": "ACTIVE",
    "path": "/api",
    "vendor": "IBM",
    "defaultLanguage": "en",
    "description": {
        "name": "Work Queue Items Additional Details",
        "language": "en",
        "description": "Work Queue Items Additional Details"
    },
    "devConfigurations": [
        {
            "name": "businessObject",
            "values": [
                "refreshOptions"
            ],
            "metaInformation": "stateSubscription"
        },
        {
            "name": "iframe.baseUrl",
            "values": [
                "UIHub"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "iframe.path",
            "values": [
                "/template/DEFAULT_INVENTORY_DETAIL_LAYOUT_TEMPLATE"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "iframe.queryParams",
            "values": [
                "inventoryId={{ iframeQueryParam.id }}&inventoryOther={{ iframeQueryParam.rowData.product.partNumber }}&hiddenLayoutSections=queue"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "iframe.token",
            "values": [
                "{{ token.raw }}"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "iframe.cuiToken",
            "values": [
                "{{ cuiToken }}"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "iframe.tenantId",
            "values": [
                "{{ tenantId }}"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "iframe.offeringId",
            "values": [
                "{{ offeringId }}"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "iframe.viewData",
            "values": [
                "{{ viewData }}"
            ],
            "metaInformation": "widgetOption"
        },
        {
            "name": "token",
            "values": [
                "refreshOptions"
            ],
            "metaInformation": "stateSubscription"
        },
        {
            "name": "cuiToken",
            "values": [
                "refreshOptions"
            ],
            "metaInformation": "stateSubscription"
        },
        {
            "name": "iframeQueryParam",
            "values": [
                "refreshOptions"
            ],
            "metaInformation": "stateSubscription"
        },
        {
            "name": "transformation",
            "values": [
                "{\"errors\":\"{{#? this.errors}}\"}"
            ],
            "metaInformation": "widgetOption"
        }
    ],
    "userConfigurations": [
        {
            "name": "chartType",
            "values": [
                "iframe"
            ]
        }
    ],
    "adminConfigurations": []
}

Result

Result of the out of stock inventory data table displayed on a page
Result of the out of stock inventory data table displayed on a page