The Object Table widget is used to display object data in a tabular format. Module builders configuring an Object Table widget can use features including:
The below screenshot shows an example of a configured Object Table displaying Flight Alert data:
If your object has a property that stores a URL to an image, you can add the type class hubble:icon
to display the image instead of the icon that was selected when setting up the object type. This feature allows you to show pictograms or images to show alongside your data.
For the Object Table widget, the core configuration options are the following:
Columns: This section determines the columns that will be displayed within the Object Table. This configuration option is revealed in more detail to show the property types seen within the initial object set, once that object set is populated. In addition, special column types allow module builders to display linked objects, parameterized URL links, time series data, and derived columns generated on-the-fly with a function. Users in View mode can also choose to configure the columns shown to them. By selecting Configure columns from the arrow next to a column header, viewers can choose the columns and the order to display them in the Object Table. Review the time series properties section below for more information on time series data, and the function-backed columns section for more information on how to configure derived columns.
The displayed column name is a text field that defaults to the object type’s property name when added. If the object type's property name is later updated in the Ontology, the displayed column name in the Object Table will not automatically change.
Enable inline editing: When enabled, this toggle allows configuration of cell-level edits within the Object Table. See the Inline Edits (cell-level writeback) section below for more information on how to configure this advanced feature.
Default sort(s): This setting allows one or more default sorts to be applied to the table. Module builders can sort on both visible property types shown within the table or hidden property types not displayed. If no sort is applied, the data is not sorted. We recommend specifying a sort where necessary.
To save your column configuration, take the following steps to use a string array variable with state saving:
The tutorial below references a Flight Alert object type that may not be available in your Foundry environment. Use the below as a guide and then follow along by using a comparable object type from your Foundry instance. To learn more about Functions, see the dedicated Functions documentation.
To create a function that returns one or more function-backed columns, you'll need to meet the following specifications:
ObjectSet<ObjectType>
parameter (and can optionally include other input parameters). This ObjectSet<ObjectType>
parameter will enable the objects displayed in the table to be passed into the function to then generate the desired derived column. Note that an ObjectType[]
parameter will also work here, but this less performant option is not recommended.FunctionsMap<ObjectType, CustomType>
. This will enable the function to return a map of object → a custom type that can include one or more fields. Learn more about custom types.Once a function that meets the above criteria is configured and published, you’ll be able to successfully configure a “Function-backed property” column within the Object Table configuration. See below for a more detailed tutorial.
The Object Table widget supports the display of function-backed properties which are calculated on-the-fly via Functions. This offers module builders considerable flexibility to display columns that could, for example:
This example uses a function-backed property to help users view and work with the priority of a Flight Alert
ticket. Here, the goal is to examine an existing property called Time of Delay
(in Hours) and, from this property, generate a new, function-backed column called Urgency
. The derived Urgency
column marks long delays (over 4 hours) as “High” urgency, moderate delays (between 2 and 4 hours) as “Medium” urgency, and shorter delays (of less than 2 hours) as “Low” urgency. This Urgency
derived property should make it easier for users to quickly scan the Object Table and determine which alerts to action first.
To configure this function-backed property, the first step is to configure a function that takes in the expected input (e.g., an object set of Flight Alert
objects) and returns the expected FunctionsMap
output required by the Object Table for a function-backed property (e.g., a FunctionsMap
of Flight Alert
objects --> urgency strings). In this example, the logic to calculate urgency will be hardcoded into the function itself, as seen below:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
@Function() public flightAlertCalculateUrgency(flightAlerts: ObjectSet<FlightAlertWorkshopTutorial>): FunctionsMap<FlightAlertWorkshopTutorial, string>{ const map = new FunctionsMap<FlightAlertWorkshopTutorial, string>(); flightAlerts.all().forEach(flightAlert => { var hoursDelayed = flightAlert.timeOfDelayHours if (hoursDelayed! > 4) { map.set(flightAlert, "High") } else if (hoursDelayed! > 2) { map.set(flightAlert, "Medium") } else { map.set(flightAlert, "Low") } }); return map; }
Once this function has been published, configure the Urgency
derived property to be displayed in this Workshop module. First, within the Object Table’s configuration panel in the Workshop module, select the Add column button and the option to add a Function-backed property.
Within the Function-Backed Property option that appears in the Columns list, click on the “fx” Functions icon and then select the desired function. In this example, we select the flightAlertCalculateUrgency function.
Next, confirm the function version and then configure the necessary inputs for the function. Let's choose Use a runtime input to pass only the objects currently displayed in the Object Table and thus optimize the performance of our function. Alternatively, you have the option to pass in an object set variable (that is, the same object set that backs the Object Table).
The Use a runtime input option will dynamically pass only the objects currently displayed in the Object Table (rather than an entire object) into a derived column function and provide faster performance. The additional Use a variable input option allows passing in an entire object set variable instead (such as the input object set variable that backs the Object Table), but may result in slower performance.
Lastly, let’s click into the Function-backed property column cell to rename this column to something more descriptive like “Urgency”.
The end result will be the following Object Table that calculates the new derived Urgency column on-the-fly and displays this valuable additional information to users.
Next, let's walk through a more advanced example to create a single function that produces multiple function-backed properties by using a custom return type. Learn more about custom types. There are several advantages to using a single function to return multiple function-backed properties, including increased performance and clearer organization of the related derived properties code.
In this example, use a function that takes in an ObjectSet<FlightAlerts>
, traverses a Departure Airport
link to retrieve a linked Airport
object, and then returns three properties from that linked Airport
object. This will enrich the data displayed in the Object Table to include relevant information from a linked object type.
To achieve this goal, first define a custom type to use within this function. This could look like the following:
Copied!1 2 3 4 5
interface LinkedDepartureAirportProperties { airport: string; city: string; country: string; }
Then, use this custom type to write a function like the below which will return three function-backed columns for Airport
, City
, and Country
:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
@Function() public getColumnsFromLinkedDepartureAirport(flightAlerts: ObjectSet<FlightAlertWorkshopTutorial>): FunctionsMap<FlightAlertWorkshopTutorial, LinkedDepartureAirportProperties> { // Fetch all linked airports and store in dictionary, keyed by iata const iataToAirport: { [iata: string]: AirportObject } = {}; flightAlerts.searchAroundDepartureAirport().all().forEach(airport => { iataToAirport[airport.iata!] = airport; }); const map = new FunctionsMap<FlightAlertWorkshopTutorial, LinkedDepartureAirportProperties>(); flightAlerts.all().forEach(alert => { // Get airport for this alert const airport = iataToAirport[alert.departureAirportCode!]; // Skip if airport not found if (!airport) { return; } map.set(alert, { airport: airport.airport!, city: airport.city!, country: airport.country!, }); }); return map; }
Once the above function is published, it can be used to add derived columns within Workshop. Add a new Function-backed property
column to your Object Table widget that contains Flight Alert
objects as you did in the above section.
In the new column that appears in the column list, click the fx icon to select the function that will back the derived column(s). In this example, select the getColumnsFromLinkedDepartureAirport
function defined earlier in this tutorial.
Next, configure the input parameters to the selected function. In this example, the function takes a single input parameter, an object set of Flight Alert objects called flightAlerts
. Let's choose the Use a runtime input option to pass the function the objects currently displayed in the Object Table.
The Use a runtime input option will dynamically pass only the objects currently displayed in the Object Table (rather than an entire object set) into the derived column function and thus provide faster performance. The additional Use a variable input option allows passing in an entire object set variable instead (such as the input object set variable that backs the Object Table), but may result in slower performance.
Once the above step is complete, the function should run successfully and display the three expected columns in the Object Table:Departure Airport
, Departure City
, and Departure Country
. We can either stop here or edit the column display names or column order to improve how the columns are presented in the application.
Time series properties, including data generated by time series transforms, can be viewed alongside regular properties in the Object Table. A time series property is an object property that stores a history of timestamped values. See Time series properties in Workshop for more information.
In the example below, the Country
object has a conventional string property Name
, which stores the name of the country, and a time series property New Cases
, which stores a daily history of new COVID-19 cases observed in the country. The object table displays these two properties in the first two columns on the left, along with three time series derived from the New Cases
property using time series transforms: Case Acceleration
, Weekly Cases
, and Total Cases
. Each time series column displays the most recent observation in the time series on the left, and a sparkline visualizing the history of the time series on the right.
To illustrate how to configure a time series property column in the Object Table, we will walk through the set up of the Weekly Cases
column. The panels on the right side of the screen are the upper and lower parts of the configuration of the Weekly Cases
column. These are placed together on the same screen as the column itself, to give a holistic reference for the configuration and result.
First, we need to generate a time series of the weekly COVID-19 caseload using a time series transform. A time series transform performs a mathematical operation on input time series data to yield a new output time series. See Time series properties in Workshop for more information on time series transforms.
Here, we can use an aggregate transform to create the time series we need. The Add transform
button opens a transform configuration, which we can set up to generate the time series we need.
Next, we can use a time series summarizer (the red box) to generate the numeric value that is displayed in the column. A time series summarizer configures a summary statistic for time series data - that is, a value that reflects the state of the time series. Here, we use a single value summarizer to generate the value we want to display, which will be the last weekly average case count. See Time series properties in Workshop for more information on time series summarizers.
We can then configure value formatting (the blue box), under the Format Number header, and conditional formatting (the green box), under the Conditional Formatting header, to style the display of this value. Value formatting controls how the figures in the value are displayed, while conditional formatting changes the display color using a value-based rule system. In this case, we want to use compact notation, and to display the value in red if the weekly average COVID-19 case count is more than 100. See Formatting in Workshop for more information on value and conditional formatting.
Finally, we can configure the sparkline visualization that will display the history of our weekly average cases time series.
The time range selector (the red box) lets us specify the time window we want to visualize the time series for. See Time series properties in Workshop for more information on time ranges.
We can also add conditional formatting (the blue box), under the Conditional Formatting header, to change the color of the sparkline using a value-based rule system. See Formatting in Workshop for more information on conditional formatting.
Last, we can configure a baseline (the green box) to aid with interpretation of the sparkline. See Time series properties in Workshop for more information on configuring baselines.
Editing options for inline edits are defined via an Action configured in the Ontology. For more information on Actions, see the Actions tutorial. For further inline edit considerations, see the Actions inline edits documentation.
Enabling inline editing allows module users to modify cell-level data displayed within the Object Table and then save these edits to objects data. Editing options are defined via an Action configured in the ontology that must meet the following criteria to be compatible with inline edits:
Additional notes:
When configuring the Object Table widget, the toggle to Enable inline editing will appear within the Column configuration section below the Columns list. Setting this toggle to true will Enable inline editing and prompt you to select the Action you already configured within the Ontology to modify the displayed object type. In the example below, inline editing is enabled through the Flight Alert: Inline Editing Action. Beneath the Action picker, the Action parameters are mapped to the table columns through the displayed dropdown menus. You can also pass variables as Action parameters that will get passed into the Action automatically without the user needing to edit the field in the table.
After the above is configured, users can enter into editing mode with the Edit table button visible in the table footer. You can edit this button text with the Custom button text input field. You can also choose to have the table always be in inline editing mode by toggling on the Enable edit mode by default option. Once in edit mode, users can edit any modifiable column mapped to an Action parameter, as seen below. Users can stage edits for up to 20 rows at a time for function-backed Actions and up to 200 rows at a time for Actions that are not function-backed. Any staged edits can be undone with the Undo button (as seen in the left-most column of the table in the screenshot below).
Once you make your edits and are ready to submit your changes, you can press the Submit button in the bottom right corner of the table. A confirmation dialog will appear where you will again press Submit to submit your changes. If you prefer to use a one-click submit option and would like to disable this confirmation dialog, you can enable the One-click submit toggle.
Adding custom row actions to the right-click menu allows users to run actions or events on an object that is right-clicked from the object table.
To add custom row actions to the right-click menu, enable the Customize right-click menu toggle within the Right-click menu section. Setting this toggle to true will prompt you to create a right-clicked object which outputs the currently right-clicked object in the table. You can then add custom items to the menu by selecting Add item.
When you select Add item, a new menu will appear (as shown in the screenshot below) where you can customize how your menu item will be displayed within the right-click menu. You can also assign an Action to your menu item by selecting an option from the On click dropdown menu. This allows you to choose whether your menu item triggers an Action or an event. Additionally, you can use the right-clicked object you set up earlier within the Action or event.
Once configured, you will see your changes when you right-click on a row in your Object Table.