Overview

List Grid

Main component for tabular lists with filters, sorting, server-side paging, and row actions.

Use Cases

  • Enterprise tabular CRUD.
  • Operational reports with multi-column filters.
  • Very large datasets with cursorMode.

Screenshot Reference (User Manual)

  • manual__grid__01.png: inline cell edit mode in list-grid.
  • manual__grid__02.png: inline edit (row-level) mode in list-grid.

Inline Editing Metadata

Configuration in the table metadata md_props_bag:

  • md_inline_edit

- Enables inline row editing in list-grid (editable cells in row context, without opening a popup).

- Useful when you want to maintain the table UX with quick editing per record.

  • md_inline_cell_edit

- Enables "cell-by-cell" inline editing (focus on the individual cell).

- Note: in legacy configurations it may appear as md_inline_cell_editing; the runtime behavior is the same.

- Runtime promotion: when md_inline_cell_edit is true, the component forces

md_inline_edit = true at runtime regardless of the DB value.

Both UX modes need the action column visible, so they are mutually

non-exclusive at the rendering level.

  • md_batch_save

- Enables batch saving of pending changes (Save changes / Cancel changes).

- When used with inline-cell, changes remain pending until explicit save.

- Prerequisite: md_batch_save takes effect only if md_inline_cell_edit is true.

With md_inline_cell_edit:false the flag is ignored at runtime and the

"Save changes / Cancel changes" buttons are not rendered.

Valid Combinations

md_inline_editmd_inline_cell_editmd_batch_saveRuntime Result
truefalseanyRow-level inline edit with pencil. md_batch_save ignored.
falsetruefalseCell-by-cell autosave on blur. md_inline_edit forced to true at runtime.
falsetruetrueCell-by-cell with pending buffer + Save / Cancel changes toolbar.
falsefalseanyNo inline editing. md_batch_save ignored.

Row-level inline edit example:

Snippet 1JSON
{
  "md_inline_edit": true,
  "md_inline_cell_edit": false,
  "md_batch_save": false
}

Cell-by-cell with batch save example:

Snippet 2JSON
{
  "md_inline_edit": false,
  "md_inline_cell_edit": true,
  "md_batch_save": true
}

Toolbar Export/Import

  • Export XLS:

- Shows a progress dialog with real-time percentage;

- Actions: Continue in background, Cancel task, Stop and download partial;

- In background creates a notification with progress; click reopens the dialog.

  • Import XLS/XLSX (if md_importable = true):

- Progress dialog after confirmation;

- Actions: Continue in background, Cancel import (rollback), Stop and partial commit;

- At the end of import creates a summary notification that navigates to the route.

Metadata Config

Key settings in md_props_bag and column metadata.

Snippet 3JSON
{
  "serverProperties": {
    "queryOptimization": {
      "enabled": true,
      "countPolicy": "cursor",
      "sqlServerHint": "none"
    }

md_props_bag: toolbar

Opt-in flags that hide blocks of the list-grid toolbar (caption-bar). All under md_props_bag.toolbar.* (parsed at runtime as tableMetadata.extraProps.toolbar).

Snippet 4JSON
{
  "toolbar": {
    "hideManageState": true,
    "hideBatchActions": true
  }
}
  • hideManageState (boolean, default false): hides in the caption-right the "Manage state" button (bookmark icon) + the saved-states <select>. Useful for hardcoded / demo routes where the saved-state feature (persistence per user_id + route via MetaService) doesn't make sense — e.g. Pattern 3 pure OData without registered route metadata.
  • hideBatchActions (boolean, default false): hides in the caption-left the "Save changes" (pi-save) + "Discard changes" (pi-times) buttons + the changes count indicator (grid-changes-indicator, pencil badge + count). Generated by the framework when md_inline_cell_editing + md_batch_save are active. Designed for nested grids inside a parametric-dialog: the parent's save/cancel persists master + rows in one shot via the framework batch save, and the duplicate buttons on the nested grid confuse the UX.

Example nested rows in custom edit-form (runtime patch):

Snippet 5ts
this.righeDs.metaInfo.tableMetadata.extraProps = Object.assign(
  this.righeDs.metaInfo.tableMetadata.extraProps || {},
  { toolbar: { hideManageState: true, hideBatchActions: true } }
) as any;

TS type in `metadati_tabella.ts` (extraProps.toolbar property). The flags do NOT disable the underlying md_batch_save logic (changes are still tracked); they only remove the toolbar UI — the actual save flows through the parent.

md_props_bag: archetypes.list

The component reads md_props_bag.archetypes.list.

Snippet 6JSON
{
  "archetypes": {
    "list": {
      "proportionalColwidth": true,
      "advancedFilter": false,
      "virtualize": {
        "enabled": true,
  • proportionalColwidth:
  • type: boolean (with tolerant parser)
  • accepted values: true, false, 1, 0, "true", "false", "1", "0"
  • runtime default: true when absent or empty
  • effect: distributes column widths proportionally (instead of px) when no user-persisted widths exist.
  • virtualize:
  • type: boolean or object
  • accepted values:
  • true/false, 1/0, "true"/"false", "1"/"0"
  • object with enabled (optional) and itemSize (optional)
  • runtime default: disabled (false) when absent
  • enabled:
  • default: true if the virtualize node is an object without enabled, otherwise tolerant parser
  • effect: enables virtualScroll on p-table
  • itemSize:
  • default: 44
  • effect: sets virtualScrollItemSize (virtual row height in px)
  • advancedFilter:
  • type: boolean (with tolerant parser)
  • runtime default: false
  • effect:
  • when true, the grid hides column filter icons (p-columnFilter) and uses the wuic-filter-bar above the table (at data-repeater/bounded-repeater level) to apply filters.

Operational note:

  • The md_props_bag suggest in the metadata editor also exposes the checkable archetypes.list.advancedFilter node.

Paging: md_pagesize and md_page_size_choice

The grid uses md_pagesize as the default page size and md_page_size_choice as the list of selectable values in the paginator.

Runtime rules:

  • If md_pagesize is greater than the maximum value present in md_page_size_choice, the framework automatically adds md_pagesize to the options list;
  • The list is normalized (valid numbers, deduplication, ascending sort).

Example:

  • md_pagesize = 200
  • md_page_size_choice = "10,25,50,100"
  • runtime result: 10,25,50,100,200

Forced Virtualization on High Page Size

When the user selects in the paginator a pageSize >= 1000:

  • virtualization is automatically forced even if md_props_bag.archetypes.list.virtualize is absent or disabled;
  • virtualScrollItemSize is forced to the default value 44.

This behavior protects the table rendering on very large pages.

Events and Subscriptions (Host)

wuic-list-grid exposes runtime events useful for intercepting the render cycle and p-table callbacks on the host project side.

Available events:

  • onAfterRender: emitted at the end of grid data binding (rows, totalRecords, metaInfo, datasource).
  • onBeforeRowRender: emitted before the logical rendering of a single row; supports cancel via event.cancelRender().
  • onAfterRowRender: emitted after the logical rendering of a single row.
  • onPaging: emitted on paging events (p-table onPage).
  • onSorting: emitted on sorting events (p-table onSort).
  • onFiltering: emitted on filtering events (p-table onFilter).
  • onPTableSelectionChange: emitted on row selection change.
  • onPTableRowExpand: emitted on row expand.
  • onPTableRowCollapse: emitted on row collapse.
  • onPTableColumnResize: emitted on column resize.
  • onPTableColumnReorder: emitted on column reorder.

Example 1: Direct Binding in Template

Snippet 7HTML
<wuic-list-grid
  [hardcodedDatasource]="citiesDs"
  (onAfterRender)="handleAfterRender($event)"
  (onBeforeRowRender)="handleBeforeRowRender($event)"
  (onAfterRowRender)="handleAfterRowRender($event)"
  (onPaging)="handlePaging($event)"
  (onSorting)="handleSorting($event)"

Example 2: Subscribe via ViewChild

Snippet 8ts
import { AfterViewInit, OnDestroy, ViewChild } from '@angular/core';
import { Subscription } from 'rxjs';
import {
  ListGridAfterRenderEvent,
  ListGridAfterRowRenderEvent,
  ListGridBeforeRowRenderEvent,
  ListGridComponent

rowCustomSelect — actual signature (gotcha)

<wuic-list-grid> accepts a [rowCustomSelect] input to hook into row selection (opening a "pick a document" dialog, master-detail flow, etc.). The TypeScript signature declared in list-grid.component.ts:140 reads:

Snippet 9ts
@Input() rowCustomSelect: (rowData: any, $event: any, dt: Table) => void;

However at runtime the callback is invoked with arguments reversed — the framework calls rowCustomSelect($event, rowData, dt) (see dynamic-template.component.ts:447 and dynamic-card-template.component.ts:205).

Symptom of wrong arg order: rowData?.id is undefined → early-return guard in your handler → the callback returns silently and your dialog/action never fires. No console error.

Correct form (matches runtime invocation):

Snippet 10ts
onRowSelected = (_event: any, rowData: any, _dt: any): void => {
  // rowData is the record provided by list-grid
  this.handleSelection(rowData);
};

Template usage:

Snippet 11HTML
<wuic-data-source #ds [hardcodedRoute]="'preventivi'" [autoload]="true"></wuic-data-source>
<wuic-list-grid [hardcodedDatasource]="ds" [rowCustomSelect]="onRowSelected"></wuic-list-grid>

> Note: tests in designer.component.spec.ts (e.g. line 512) invoke the callback with ({currentTarget: rowCell}, {id: 42}, null), confirming the ($event, rowData, dt) order. If the framework eventually aligns the declared signature, this page will be updated as well.

Screenshot

List grid - interazione base
List grid - interazione base
list-grid / list-grid-main
list-grid / list-grid-main
list-grid / manual-grid-01
list-grid / manual-grid-01
list-grid / manual-grid-02
list-grid / manual-grid-02