

Visit Relativity Learning to explore additional learning opportunities for this topic.
Last date modified: June 30 2025
Relativity Lists provides a robust offering of APIs to allow developers to write custom code to extend the functionality of their list pages. By creating an interaction script, developers can subscribe to events, usually beginning with an on
prefix (e.g. onItemListPopulated
), or access additional service APIs that allow a variety of functionality to be executed, including custom widget registration, custom modal creation, and data source overrides.
The APIs are arranged into objects based on their function. You can start by looking at the 2 top level objects in which all APIs and properties are contained:
Relativity.Lists allows extension developers to use any valid JavaScript, and developers can assume that the following objects are available at global scope:
interactionApi
convenienceApi
// The developer can sign up for event based callbacks
interactionApi.config.onConfigLoaded(initialize);
// The developer can declare functions to handle callbacks and make additional API calls
function initialize() {
interactionApi.widget.registerWidgetType(...);
}
For more examples, see the Common Migration Scenarios below.
Relativity.Lists creates a function using the text of the script and executes it like so:
new Function(
"interactionApi", "convenienceApi"
`
"use strict";
// script text
`
)(interactionApi, convenienceApi);
To associate an interaction script to be run on the Relativity List page for a specific object type, the file needs to be included in a List Page Interaction Event Handler.
The javascript file name must begin with lists.ext.
to be executed on the Relativity Lists page.
Existing classic List Page interaction scripts associated to an object type by a Classic List Page Interaction Script are now deprecated and will no longer be supported in the future (see the Classic List Page Deprecation Notice).
Until the classic List Page is no longer supported, object types with associated classic List Page interaction scripts will continue to load the classic List Page. Once a new Relativity Lists interaction script (with a javascript file name beginning with lists.ext.
) is associated to that object type, the new Relativity Lists page will automatically be used instead to execute the new interaction script.
For testing purposes, an administrator can manually enable/disable loading the new Relativity Lists page for an object type on the Relativity Lists Toggle tab. Here are the steps to complete this:
To migrate an existing classic List Page interaction script to use the new Relativity Lists API, refer to the information below to determine the new API to use.
Relativity Lists doesn't require packaging interaction scripts as a module or an IFFE. These scripts are standard JavaScript. You can also assume that the Interaction API and Convenience API exist in the global scope. Previously, interaction scripts were required to be in a RequireJS module that returned an initializer function, which executed in way that passed the object containing the service APIs to an interaction script.
Classic API Name | Classic Event | Relativity Lists API | Notes |
---|---|---|---|
Page Navigation API | listPageChange (pageNavigationAPI) | No longer supported | |
New Item Button API | newItemButtonInit (buttonAPI) | ToolbarApi (see modifyToolbarContent) | |
Cell Formatter API | cellFormattersInit (cellFormatterApi) | DataSourceApi (see registerColumnFormatter) | This API is no longer event-based. The cell formatters should be registered when the interaction script is initialized. |
Data Source Override API | dataSourceInit (dataSourceAPI) | DataSourceApi (see registerDataSource) | This API is no longer event-based. The data source override should be registered when the interaction script is initialized. |
View API | viewChange (viewChangeAPI) | ItemListApi (see onViewChange) | |
Widget Menu Customization API | widgetMenuCreate (widgetMenuAPI) | WidgetApi (see onWidgetMenuCreate) |
Classic API Name | Classic Service Name | Relativity Lists API | Notes |
---|---|---|---|
Promise API | api.promise | No longer supported | All modern browsers compatible with Relativity support promises. |
Events API | api.eventService | No longer supported | |
Kepler Provider API | api.keplerProviderService | ConvenienceApi.RelativityHttpClient | |
Common Utilities API | api.commonUtilities | ConvenienceApi.RelativityHttpClient | "commonConstantsAndObjects" is no longer provided |
Modal API | api.modalService | ModalApi | |
Toolbar API | api.toolbarService | ToolbarApi | |
CustomWidget API | api.customWidgetService | WidgetApi |
formatterApi.setFormatter("columnName", function (defaultValue, columnOptions, rowData, api) {
// Modify or replace the return value with what is to be shown in the cell
return api.getCellData(defaultValue);
}
interactionApi.dataSource.registerColumnFormatter({name: "columnName"}, {
format: (_content: any, dataItem: FormatterDataItem) => {
// Modify or replace the return value with what is to be shown in the cell
return _content;
},
formatCsv: (_content: any, dataItem: FormatterDataItem) => { }
});
overrideApi.setItemListDataSource(function(itemListDataSourceParams) {
return {
getData: {
method: function(payload) {
// ...
}
},
inboundTransformer: {
method: function(data) {
// ...
}
},
outboundTransformer: {
method: function(data) {
// ...
}
}
};
});
interactionApi.dataSource.registerDataSource("ItemListWidget", (workspaceID: number, artifactTypeID: number) => {
return {
getData(activeArtifactID: number | undefined, start: number, pageLength: number, filters: Filter, sorts: dataManagement.itemList.Sort[], fieldIDs: number[], fieldCollection?: ItemListFieldCollection, activeView?: View,
sampleState?: SampleState, browserState?: BrowserPanelState, relationalFieldId?: number, activeSavedSearchID?: number): Promise<void | ObjectManagerData> {
// ...
},
transformInbound(data: any, columns: any[], workspaceID: number, callbacks: ItemListDataSourceCallbacks): ItemListData {
// ...
},
transformMultiReflectedFields(fields: dataManagement.itemList.Data[], fieldCollection: ItemListFieldCollection): void {
// ...
}
}
});
function() {
function sampleHandler(api) {
// Illustrates a function that handles page change events. It takes the Page Navigation API as a parameter.
function handleNewItemButtonCustomizeEvent(buttonApi) {
buttonApi.setButton({
text: "Open my custom modal",
eventName: "show_my_modal"
});
}
return {
// Subscribe to the "newItemButtonInit" event.
newItemButtonInit: handleNewItemButtonCustomizeEvent
};
}
return sampleHandler;
}
const newButton = document.createElement("button");
newButton.innerText = "Open my custom modal";
newButton.classList.add("rwa-button");
newButton.addEventListener("click", async () => {
// Open a modal
});
interactionApi.toolbar.v1.modifyToolbarContent("header", "_default", (_api: any, content: ToolbarContent): ToolbarContent => {
if (content.left) {
content.left.splice(2, 1); // Remove original button
content.left.splice(2, 0, newButton); // Add new button with custom action
} else {
content.left = [newButton];
}
return content;
});
An object rule can also be used to override the New Item Button's URL. See New Button Override for more information.
const WIDGET_TYPE_NAME = "Widget Type Name";
interactionApi.widget.registerWidgetType(WIDGET_TYPE_NAME, (state: WidgetStateInfo) => {
// Perform any setup needed (open modal to gather preferences, etc)
// Update the passed stateData object with any state information to save
const WIDGET_TITLE = "Widget Title";
stateData.settings.title = WIDGET_TITLE;
// Build HTML element to display in widget
const widgetRef: HTMLElement = new HTMLElement();
// Build widget menu items
const menuItems: WidgetMenu[] = [{
title: "Properties",
visible: true,
items: [{
name: "Edit Widget",
visible: true,
type: "link",
icon: "edit",
onClick: () => {
/** Open modal to edit the widget */ }
},
{
name: "Export Widget",
visible: true,
type: "link",
icon: "share",
onClick: () => {
/** Export widget information */ }
}
]
}];
// Update/save the state information
interactionApi.widget.addOrUpdateWidget(WIDGET_TYPE_NAME, stateData, stateData.settings.id);
// Return WidgetInstance object
return {
wgtRef: widgetRef,
menu: menuItems,
title: WIDGET_TITLE
}
as WidgetInstance;
});
Relativity Lists caches all extension scripts in an IndexedDB with the path relativityLists > scripts
. When a new version of a script is identified, it will pull the new version from across the network and update the cache with the new script. This cache is keyed by the version of the application that is associated with the extension script, so developers will need to be sure to update their application version when deploying updates to their extension scripts.
For manual dropping or re-adding of extension scripts through Resource Files, the updates will not take effect as the cache will not identify that a new script needs to be pulled since the version number remains the same. To workaround this issue developers can:
RL_EXTENSION_DEVELOPER
and set it to true
which will force a refresh of all script resource files with every page load Why was this not helpful?
Check one that applies.
Thank you for your feedback.
Want to tell us more?
Great!
Additional Resources |
|||
DevHelp Community | GitHub | Release Notes | NuGet |