List View Events
Overview
List view function extensions let you hook into list lifecycle events in SolidX.
Use them to:
- Modify the outgoing list query/filter before API fetch
- Transform list records after they are loaded
- Adjust list layout dynamically at runtime
You author listener functions, register them with registerExtensionFunction, and reference them in your list view layout JSON.
Supported Events
Based on SolidListView.tsx, list view supports these lifecycle events:
onBeforeListDataLoad- runs just before list API call. Best for filter/query shaping.onListLoad- runs after list data is loaded. Best for data/layout transformation.
Event Execution Behavior
Current list lifecycle flow:
- List state is prepared (pagination, sort, filters, populate, locale, archived toggle).
onBeforeListDataLoadexecutes (if configured).- If the handler returns
filterApplied: truewithnewFilter, that filter object is used for the API request. - List API request runs.
onListLoadexecutes (if configured) with fetched records.- If returned,
newListDataand/ornewLayoutare committed to state.
Project Structure & File Paths
List Event Listeners
- Scope: list-view event listeners for a specific
<module, model>pair. - Mandatory listener location:
solid-ui/src/extensions/<module-name>/<model-name>/list-event-listeners/
- Do not place list-event listeners in generic folders when module/model is known.
Default file selection for list event changes:
- Create or update a TS/TSX listener inside:
solid-ui/src/extensions/<module-name>/<model-name>/list-event-listeners/
- Register the listener in:
solid-ui/src/extensions/solid-extensions.ts
- Keep registration key aligned with layout metadata event references (
onBeforeListDataLoad,onListLoad).
Example structure:
solid-ui/src/extensions/
├── solid-extensions.ts
└── library/
└── book/
└── list-event-listeners/
└── bookListViewChangeHandler.ts
Creating a Handler
Example with both events in one handler:
import type { SolidBeforeListDataLoad, SolidLoadList, SolidListUiEventResponse } from "@solidxai/core-ui";
const handleBookListViewChange = (
event: SolidBeforeListDataLoad | SolidLoadList
): SolidListUiEventResponse => {
// 1) Before fetch: enforce active-only records
if (event.type === "onBeforeListDataLoad") {
const nextFilter = structuredClone(event.filter || {});
const existing = Array.isArray(nextFilter.$and) ? nextFilter.$and : [];
nextFilter.$and = [...existing, { isActive: { $eq: true } }];
return {
filterApplied: true,
newFilter: nextFilter,
};
}
// 2) After fetch: annotate rows for UI usage
if (event.type === "onListLoad") {
const enriched = (event.listData || []).map((row: any) => ({
...row,
_uiRisk: row.score >= 10 ? "high" : "normal",
}));
return {
dataChanged: true,
newListData: enriched,
};
}
return {};
};
export default handleBookListViewChange;
Registering the Handler
Register the listener with an alias in solid-extensions.ts:
import handleBookListViewChange from "./library/book/list-event-listeners/bookListViewChangeHandler";
import { registerExtensionFunction } from "@solidxai/core-ui";
registerExtensionFunction("bookListViewChangeHandler", handleBookListViewChange);
Using Handlers in Layout Metadata
Reference the handler alias in list layout JSON:
{
"name": "book-list-view",
"layout": {
"type": "list",
"onBeforeListDataLoad": "bookListViewChangeHandler",
"onListLoad": "bookListViewChangeHandler"
}
}
Event Payload (Types)
onBeforeListDataLoad payload
export type SolidBeforeListDataLoad = {
type: SolidUiEvents; // "onBeforeListDataLoad"
fieldsMetadata: FieldsMetadata;
viewMetadata: SolidView;
listViewLayout: ListLayoutType;
filter?: any; // current query/filter object
queryParams?: any; // menu/action context
user: any;
session: Session;
params?: SolidListViewParams;
};
onListLoad payload
export type SolidLoadList = {
type: SolidUiEvents; // "onListLoad"
listData: any[];
fieldsMetadata: FieldsMetadata;
totalRecords: number;
viewMetadata: SolidView;
listViewLayout: ListLayoutType;
queryParams?: any; // menu/action context
user: any;
session: Session;
params?: SolidListViewParams;
};
Returning Changes
List event handlers return SolidListUiEventResponse:
export type SolidListUiEventResponse = {
filterApplied?: boolean;
newFilter?: any;
dataChanged?: boolean;
newListData?: any[];
layoutChanged?: boolean;
newLayout?: LayoutNode;
};
Usage rules:
- For
onBeforeListDataLoad: returnfilterApplied: truewithnewFilterto override request filter/query. - For
onListLoad: returndataChanged: truewithnewListDatato replace records. - For layout mutations: return
layoutChanged: truewithnewLayout.
Common Patterns
- Pre-filtering by tenant/role/context in
onBeforeListDataLoad - Enforcing default sort or locale-aware query options in
onBeforeListDataLoad - Adding computed display-only properties in
onListLoad - Runtime layout toggles (column visibility/labels) in
onListLoad
Troubleshooting
- Handler does not run -> verify metadata key (
onBeforeListDataLoad/onListLoad) and registration alias match exactly. - Filter changes not reflected -> ensure you return both
filterApplied: trueandnewFilter. - Data changes ignored -> ensure
dataChanged: trueandnewListDataare both returned. - Layout not updating -> ensure
layoutChanged: truewith a validnewLayout.