Sorting and pagination
Return a stable page from the complete sorted result.
Use default sorting to make the first screen useful. The toolbar lets users change the sort and page size; your list action applies those choices before slicing the result.
Configuration example
Start from the React quick start or Vue quick start. The following file extends their product catalog. Pass this configuration through getTableConfig in React or config in Vue.
import { defineTableConfig } from "@/components/ui/yayaw-table/config/helpers";
import { productConfig } from "./product-config";
export const sortingConfig = defineTableConfig({
...productConfig,
columns: {
...productConfig.columns,
sort: [
{ id: "stock", desc: true },
{ id: "name", desc: false },
],
},
table: {
...productConfig.table,
enableSorting: true,
enablePagination: true,
defaultPageSize: 20,
pageSizeOptions: [10, 20, 50],
},
});import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";
export const sortingConfig = defineTableConfig({
...productConfig,
columns: {
...productConfig.columns,
sort: [
{ id: "stock", desc: true },
{ id: "name", desc: false },
],
},
table: {
...productConfig.table,
enableSorting: true,
enablePagination: true,
defaultPageSize: 20,
pageSizeOptions: [10, 20, 50],
},
});Default sort
The sort a table starts from is, in order:
the sort in the URL (
<tableId>-sort);the saved view being opened, or the initial view;
columns.sort.
With none of them, no sort is sent and every mode keeps the order your list action returns: the table adds no implicit order, by id, date or anything else. Only the Feed view defines its own order when nothing is sorted: its date column, newest first. Resetting the table state returns to columns.sort.
React and Vue follow the same rule. Earlier React versions ignored columns.sort on first load and applied it only when the default view was chosen again, so a host that orders by id when no sort is sent showed React by id and Vue by the configured column. Upgrade to get the same first screen in both.
Apply the query in order
Filter the authorized dataset, apply every sort in order, add a stable ID tie-breaker, then paginate. A page sorted after it is fetched does not represent the global order. Return meta.totalCount for all matching rows and meta.pageCount for the chosen page size.
Sort by several columns
Users can combine sorts in React and Vue. In the React sort menu, clicking a column adds it after the existing sorts, a second click reverses it and a third removes it; numbers show the priority once two sorts apply. Vue edits the same ordered list with one rule per sort. Your list action receives every sort in order, in both sorting and orderBy.
Manual order per view
Set table.manualOrder: true and provide actions.reorder to offer Manual order in the sort menu. It is a sort like the others, saved with the view, but each view keeps its own order: moving a record in one view does not change another, and records are never modified. A request sorted this way contains the sort id __manual and a viewId (the saved view, or null for the default view); sort by the order you stored for that view and put unordered records last. See server actions for reorder.
Page numbers
The list contract uses one-based page. UI pagination uses zero-based pageIndex. React commonly sends limit and orderBy; Vue exposes pageSize and sorting, while the compatibility helpers accept both forms. The quick-start list-records.ts handles these aliases.
The page shown
A search, a filter or a sort changed in the table starts on the first page; choosing the current one again keeps the page. A link keeps the page it names, when it opens and on back and forward. A page past the last one, from an old link or after rows are removed, moves to the last page once your list action answers: answer such a page with meta.totalCount and meta.pageCount and no rows, not an error.
React and Vue behave alike since v3.9.1. Before it, React kept the page after a new search, filter or sort, so a search from the second page could show an empty table, and showed a page past the last one empty; Vue opened a link on the first page, whatever page it named. Upgrade to get the same pages in both.
Auto page size and stable selection
The current distribution can fit the page to the table’s available height. This still sends a numeric size to the backend. Bound server page sizes, return honest totals, and keep getRowId independent of the page index. See bulk selection and server actions.
Sort by stock, then name
Keep numeric ordering for stock and use Name to break ties. Sorting is applied to all matching records before the requested page is extracted.
Copy this complete configuration beside product-config.ts. Use () => exampleConfig as React’s getTableConfig, or :config="exampleConfig" in Vue.
Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table/config/helpers";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
columns: {
...productConfig.columns,
sort: [
{ id: "stock", desc: true },
{ id: "name", desc: false },
],
},
table: { ...productConfig.table, enableSorting: true },
});Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
columns: {
...productConfig.columns,
sort: [
{ id: "stock", desc: true },
{ id: "name", desc: false },
],
},
table: { ...productConfig.table, enableSorting: true },
});Make pagination easy to exercise
Three sample products and a two-row page make the second page visible. Return the total number of matching rows, not the number of rows on this page.
Copy this complete configuration beside product-config.ts. Use () => exampleConfig as React’s getTableConfig, or :config="exampleConfig" in Vue.
Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table/config/helpers";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
enablePagination: true,
defaultPageSize: 2,
pageSizeOptions: [2, 10, 20],
},
});Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
enablePagination: true,
defaultPageSize: 2,
pageSizeOptions: [2, 10, 20],
},
});