Skip to main content

Pagination

Grid pagination presents the paging state of the bound FdcDataSet. The grid does not split an already loaded result set into pages by itself; the dataset requests page-sized slices from its adapter, and the grid renders controls for navigating that state.

The sample below contains 1,000 order records and lets you switch live between the two paging models. Standard mode loads 25 rows per page, requests the exact total count, and exposes record information, numbered navigation, and a page-size selector. Infinite mode loads 50-row chunks and appends additional chunks as scrolling approaches the end of the loaded content.

1,000 paged order records
Loading FDC sample…
FdcDataSet createOrdersDataSet(FdcDataPagingMode mode) {
return FdcDataSet(
fields: orderFields,
adapter: orderAdapter,
paging: FdcDataPagingOptions(
enabled: true,
pageSize: mode == FdcDataPagingMode.standard ? 25 : 50,
maxPageSize: 100,
requireTotalCount: mode == FdcDataPagingMode.standard,
mode: mode,
infiniteLoadThreshold: 0.70,
),
);
}

// Switch between two dataset instances created from the same adapter data.
SegmentedButton<FdcDataPagingMode>(
segments: const [
ButtonSegment(
value: FdcDataPagingMode.standard,
label: Text('Standard'),
),
ButtonSegment(
value: FdcDataPagingMode.infinite,
label: Text('Infinite'),
),
],
selected: {mode},
onSelectionChanged: (value) {
setState(() => mode = value.single);
},
);

FdcGrid(
dataSet: mode == FdcDataPagingMode.standard
? standardOrders
: infiniteOrders,
columns: orderColumns,
toolbar: const FdcGridToolbar(
items: <FdcGridItem>[
FdcGridMainMenuButton(),
FdcGridSearchBar(
placement: FdcGridItemPlacement.start,
mode: FdcGridSearchBarMode.simple,
),
],
),
statusBar: mode == FdcDataPagingMode.infinite
? const FdcGridStatusBar(visible: false)
: FdcGridStatusBar(
visible: true,
items: <FdcGridItem>[
const FdcGridPagingRecordInfo(
placement: FdcGridItemPlacement.start,
),
FdcGridPagingNavigator.numbered(
placement: FdcGridItemPlacement.center,
visiblePageCount: 7,
),
FdcGridPageSizeSelector(
placement: FdcGridItemPlacement.end,
options: const <int>[25, 50, 100],
),
],
),
);

Start in Standard mode and try moving between pages or changing the page size. Then switch to Infinite and scroll toward the bottom to trigger incremental loading. Sorting and search work in both modes and restart the query against the complete adapter-backed result rather than only the currently loaded rows.

Configure the dataset

Paging starts at the dataset layer. The paging mode is part of the dataset configuration, so the showcase uses separate standard and infinite dataset instances over the same logical data source:

FdcDataSet createOrders(FdcDataPagingMode mode) {
return FdcDataSet(
fields: fields,
adapter: adapter,
paging: FdcDataPagingOptions(
enabled: true,
pageSize: mode == FdcDataPagingMode.standard ? 25 : 50,
maxPageSize: 100,
requireTotalCount: mode == FdcDataPagingMode.standard,
mode: mode,
infiniteLoadThreshold: 0.70,
),
);
}

The standard and infinite datasets can share the same adapter contract. Standard mode replaces the active page; infinite mode appends sequential chunks.

pageSize controls the adapter request limit. In standard paging mode, opening another page replaces the rows currently held in the dataset view.

Use requireTotalCount: true when the UI needs exact page counts, record ranges, or last-page navigation. The adapter must then return the total number of records matching the active filter, sort, and search criteria.

For the underlying dataset paging API and infinite mode, see DataSet Paging.

Add paging controls to the grid

Paging controls are regular shared grid items. They can be composed in the toolbar or status bar.

FdcGrid(
dataSet: orders,
columns: orderColumns,
statusBar: FdcGridStatusBar(
visible: true,
items: <FdcGridItem>[
const FdcGridPagingRecordInfo(
placement: FdcGridItemPlacement.start,
),
FdcGridPagingNavigator.numbered(
placement: FdcGridItemPlacement.center,
visiblePageCount: 7,
),
FdcGridPageSizeSelector(
placement: FdcGridItemPlacement.end,
options: const <int>[25, 50, 100],
),
],
),
)

The sample deliberately places the three paging concerns in separate status-bar zones:

ControlPurpose
FdcGridPagingRecordInfoShows the current global record range and total count.
FdcGridPagingNavigator.numbered(...)Shows first, previous, numbered page, next, and last navigation.
FdcGridPageSizeSelectorLets the user change the page size from an allowed set.

Numbered and input navigation

Two paging navigator styles are available.

Use numbered navigation when users benefit from seeing neighboring page positions:

FdcGridPagingNavigator.numbered(
visiblePageCount: 7,
)

Use input navigation when the number of pages can be very large and direct page entry is more useful than a row of page buttons:

FdcGridPagingNavigator.input()

Both variants bind to the same dataset paging state. Choose the interaction model that best matches the expected result size and available horizontal space.

Page size changes

FdcGridPageSizeSelector delegates page-size changes to the dataset paging controller:

FdcGridPageSizeSelector(
options: const <int>[25, 50, 100],
)

Changing the page size reloads the paged view from the first page. Every offered value must be valid for the dataset's configured maxPageSize.

Application code can make the same change directly:

await orders.paging.setPageSize(50);

Global row numbers across pages

When row numbers are enabled, the row indicator shows the record's global position in the paged result instead of restarting from 1 on every page:

const FdcGridRowIndicator(
visible: true,
options: FdcGridRowIndicatorOptions(
showRecordStatus: true,
showRowNumbers: true,
),
)

For example, with a page size of 25, page two displays row numbers 26 through 50.

Paged query operations apply to the complete logical result set:

  • sorting rebuilds the page order through the adapter;
  • filtering recalculates page boundaries for the filtered result;
  • global search runs against the complete searchable result;
  • the total count reflects the active query when exact totals are requested.

This is an important distinction from client-side manipulation of only the 25 records currently visible in the grid.

Infinite paging

FdcDataPagingMode.infinite accumulates sequential chunks as the user scrolls. In the sample, each request loads 50 records and infiniteLoadThreshold: 0.70 starts the next request when scrolling reaches roughly 70% of the currently loaded extent.

Numbered page navigation, page-size selection, and page-oriented record information are intentionally hidden in infinite mode because those controls do not match an accumulating scrolling model.

Use Standard when users need explicit page positions, direct navigation, exact page counts, or configurable page size. Use Infinite when the primary interaction is continuous exploration of a large result set. The adapter contract remains offset/limit based in both modes.