{"id":21334900,"url":"https://github.com/vlsergey/react-bootstrap-pagetable","last_synced_at":"2025-07-12T12:30:49.958Z","repository":{"id":45979383,"uuid":"360441194","full_name":"vlsergey/react-bootstrap-pagetable","owner":"vlsergey","description":"Ready-to-use-in-SPA table, based on react-bootstrap Table component.","archived":false,"fork":false,"pushed_at":"2021-11-23T09:18:45.000Z","size":26556,"stargazers_count":4,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-13T09:48:00.219Z","etag":null,"topics":["bootstrap","javascript","react","reactjs","table"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vlsergey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-22T08:08:50.000Z","updated_at":"2022-01-12T14:12:14.000Z","dependencies_parsed_at":"2022-08-26T08:01:23.865Z","dependency_job_id":null,"html_url":"https://github.com/vlsergey/react-bootstrap-pagetable","commit_stats":null,"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vlsergey%2Freact-bootstrap-pagetable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vlsergey%2Freact-bootstrap-pagetable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vlsergey%2Freact-bootstrap-pagetable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vlsergey%2Freact-bootstrap-pagetable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vlsergey","download_url":"https://codeload.github.com/vlsergey/react-bootstrap-pagetable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225820292,"owners_count":17529138,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootstrap","javascript","react","reactjs","table"],"created_at":"2024-11-21T23:36:06.562Z","updated_at":"2024-11-21T23:36:07.283Z","avatar_url":"https://github.com/vlsergey.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @vlsergey/react-bootstrap-pagetable\n\nReady-to-use-in-SPA table component\n\n[![NPM version][npm-image]][npm-url]\n[![Build Status][travis-image]][travis-url]\n[![Downloads][downloads-image]][downloads-url]\n\nGoal of this component is provide standard and simple-to-use component to display and operate over data presented in tables. Such data are usually provided by server side using some `find...` methods with `page` and `size` arguments, as well as filtering, sorting and other options.\n\nOnline demo: [HERE](https://vlsergey.github.io/react-bootstrap-pagetable/)\n\nMain features:\n* [x] Display and navigate over pages of data\n* [x] Change size of page\n* [x] Allow actions to be executed with elements (with or without autorefresh after action completed).\n* [x] Allow selecting multiple elements and execute single action over them\n* [x] Server-side sorting (i.e. passing `sort` argument to server)\n* [x] Server-side filtering (allow to display filters and pass filter arguments to server)\n* [x] Integration with [react-router](https://reactrouter.com/) to support fetching arguments from URL and pushing changes back\n* [x] Allow user to change visibility and order of columns to be displayed\n* [x] Allow to customize what to display before and after the `Table`: page selection, page size selection, custom text, etc.\n* [ ] (TODO) Support standard renderers for date, time and other OpenAPI types\n\nAdditional small features that nice to have:\n* [x] Abort `fetch()` request if next `fetch()` is called with new arguments\n* [x] Ignore results from old `fetch()` if new one is already called\n* [x] \"Select all\" checkbox\n* [ ] (TODO) examples of custom field types with custom renderers (color)  \n\n## API\n\nInstallation:\n```\nnpm install --save @vlsergey/react-bootstrap-pagetable\n```\n\nMain component is exposed as default module export of library.\nThere are 2 main properties to define. First is `itemModel` -- defines the data\nstructure, how to display data. Second is `fetch` -- provides implementation\nof method to query data from server (or memory).\n\n```typescript\nimport PageTable from '@vlsergey/react-bootstrap-pagetable';\n\n// ...\nreturn \u003cPageTable\n         fetch={this.fetchDataImpl}\n         itemModel={itemModel} /\u003e\n```\n\nTo enable [react-router](https://reactrouter.com/) integration import another variant of `PageTable`:\n```typescript\nimport {UncontrolledWithReactRouter as PageTable} from '@vlsergey/react-bootstrap-pagetable';\n```\n\n| Property                 | Data type                                      | Default value | Description |\n| ------------------------ | ---------------------------------------------- | ------------- | ----------- |\n| **`fetch`**              | `( fetchArgs: FetchArgs ) =\u003e Promise\u003cPage\u003cT\u003e\u003e` | **required**  | See below   |\n| **`itemModel`**          | `ItemModel\u003cT\u003e`                                 | **required**  | See below   |\n| `actions`                | `Action[]`                                     | `0`           | Allows to display buttons at the bottom of page table and use them to execute actions over single or multiple elements from single page of the table. |\n| `defaultPage`            | `number`                                       | `0`           | Default page to display (0-based) |\n| `defaultSize`            | `number`                                       | `10`          | Default page size to display |\n| `defaultSort`            | `string`                                       |                       | Default page sort. One can specify only field name like `name` or field name and direction like `name,ASC` / `name,DESC`. |\n| `footerElements`         | `(() =\u003e JSX.Element)[][][]`                    |                       | Elements to be rendered by `DefaultFooter` before page at the left (0), center (1), and right side (2). By default it's actions toolbar on the first line, visible fields settings button and page index at the left and page size at the right of the second line.\n| `footerRenderer`         | `( props: HeaderFooterPropsType )`             | `DefaultFooter`       | Component (function) used to render table footer with pagination and page size selector |\n| `headerElements`         | `(() =\u003e JSX.Element)[][][]`                    |                       | Elements to be rendered by `DefaultHeader` before page at the left (0), center (1), and right side (2). By default it's visible fields settings button and page index at the left and page size at the right.\n| `headerRenderer`         | `( props: HeaderFooterPropsType )`             | `DefaultHeader`       | Component (function) used to render table header with pagination and page size selector |\n| `itemFieldCellHyperlink` | `(item: T, field: FieldModel\u003cT, unknown\u003e) =\u003e string` | `() =\u003e null` | Allow to wrap cell content in hyperlink element (`\u003ca\u003e`). Will not be used when pageTable has at least single selected element. |\n| `itemFieldCellLinkWrapper` | `(props: ItemFieldCellLinkWrapperProps\u003cT, unknown\u003e) =\u003e JSX.Element` | `DefaultItemFieldCellLinkWrapper` by default. `ReactRouterItemFieldCellLinkWrapper` when react-router integration enabled | Implement hyperlink wrapper. By default it's usual `\u003ca\u003e` element (with appropriate styling to fill whole cell). Replaced with `react-router-dom` `\u003cLink\u003e` element when integration is enabled and provided hyperlink value _is_ relative. |\n| `itemFieldCellRenderer`  | `( props: ItemFieldCellRendererProps ) =\u003e JSX.Element` | `DefaultItemFieldCellRenderer` | Allows to override default item cell renderer (including selection checkbox cell). |\n| `onSelectedIdsChange`    | `(string[]) =\u003e unknown                         | `undefined`   | Selection change listener (ids) |\n| `onSelectedItemsChange`  | `((T|undefined)[]) =\u003e unknown                  | `undefined`   | Selection change listener (items). Can return `undefined` item if selected ID is not present on current page anymore. |\n| `noContentRow`           | `( tableColumnsCount: number ) =\u003e ReactNode`   | \"_no content on this page, select another page to display_\" | What to display instead of row when no data present on the fetched page |\n| `rowsRenderer`           | `( props: RowsRendererProps ) =\u003e JSX.Element`  | `DefaultRowsRenderer` | Allows to override default rows renderer. |\n| `rowProps`               | `( item: T ) =\u003e React.ComponentProps\u003c'tr'\u003e`   | `() =\u003e ({})`  | Additional properties for inner `\u003ctr\u003e` element |\n| `size`                   | `undefined` \\| `'lg'` \\| `'sm'`                | `undefined`   | Will be passed to react bootstrap `Table` component as well as to `Button`, `Form.Control` and other inner components to change their visible size. |\n| `tableProps`             | [props of react bootstrap `\u003cTable\u003e` component](https://react-bootstrap.github.io/components/table/#table-props) | `{}` | Additional properties for inner `\u003cTable\u003e` component |\n| `urlParamsPrefix`        | `string`                                       | `\"\"`          | What is the prefix of `page`, `size`, `sort` and other URL arguments that `PageTable` should interact with. Only with [react-router](https://reactrouter.com/) integration enabled.  |\n\n### Item model\nSo far itemModel (`itemModel: ItemModel`) defines 2 properties:\n\n* `idF` (`idF: (item: T) =\u003e string`). Defines a way to get unique\nidentifier of object in the data list. It's usually object ID. Identifier\n*should* be unique in single data page scope and *shall* be unique in whole\ntable scope. Internally it's used to store selected rows identifiers and to\nprovide `key` to React element array items.\n* `fields (fields: FieldModel\u003cItemModel, FieldValueType\u003e[])`.\nList of object properties that can be displayed in the table. Some of them are visible by default, some of them are hidden. Use can change this (along with order of fields). Each field model should have following properties:\n  * `key` (`key: string`). Defines internal string key for field. Internally\n  it's used to provide `key` to React element array items. In future versions\n  it will also be used to store 'shown/hidden' lists of column. Assumed to be\n  safe to change from version to version (nothing really bad happens on change).\n  * `title` (`title: string`). Field title text. Shown in table column header\n  cell. Title is string due to DOM limitations related to `\u003coption\u003e` tag\n  behavior (for example it's used in visible fields list dialog).\n  * `description` (`description?: ReactNode`): Description of field. _Optional_.\n  Currently unused.\n  * `sortable` (`boolean`): is field sortable or not. _Optional_. Default `false`. Enabling this will render additional sorting icons in table header cell and will allow user to change sorting by clicking on header cell. Component _does not_ define a way to sort elements, only fills `sort` field in `FetchArgs` structure passed to `fetch()` function.\n  * `getter` (`getter?: ( item: I, fieldModel: FieldModel\u003cI, V\u003e, itemModel: ItemModel\u003cI\u003e ) =\u003e V`).\n  _Optional_. Defines the way to obtain field value from object structure. By\n  default obtains object property using `key`, i.e. `item[fieldModel.key]`.\n  * `render` (`render: ( props: { value: V, item: I, itemModel: ItemModel\u003cI\u003e } ) =\u003e ReactNode`). _Optional_.\n  Defines the way to render object field as table cell content. By default\n  just outputs string and number values as `ReactNode`, objects are stringified\n  using `JSON.stringify()`, `null` and `undefined` are returned as `null`.\n  Feel free to use function, React functional component or React class component\n  here. Props type is exported from library as `ValueRendererProps` interface.\n  * `headerCellContent` (`props: ( field: FieldModel\u003cItemModel, FieldValueType\u003e ) =\u003e JSX.Element`).\n  _Optional_. Allow to change default header cell react element (`\u003cth\u003e`) content.\n  By default cell title is renderer with additional icons if field is sortable.\n  * `valueCellProps` (`valueCellProps?: ( value: V, item: unknown, fieldModel: FieldModel\u003cV\u003e ) =\u003e Record\u003cstring, unknown\u003e`).\n  _Optional_. Provides additional value cell react element (`\u003ctd\u003e`) properties.\n\n#### Example\n\nData example:\n```json\n[\n  { \"id\": \"1\", \"name\": \"Alice\", \"birthday\": \"2001-02-03\" },\n  { \"id\": \"2\", \"name\": \"Bob\", \"birthday\": \"2002-03-04\" },\n  { \"id\": \"3\", \"name\": \"Carl\", \"birthday\": \"2003-04-05\" }\n]\n```\n\nPossible item model:\n```javascript\nconst itemModel = {\n  idF: ( { id } ) =\u003e id,\n  fields: [\n    { key: 'name', title: 'Name', sortable: true },\n    {\n      key: 'birthday',\n      title: 'Birth Date',\n      render: ( { value } ) =\u003e new Date( Date.parse( value ) ).toLocaleDateString(),\n      sortable: true,\n    },\n    {\n      key: 'birthyear',\n      title: 'Birth Year',\n      getter: ( { birthday } ) =\u003e new Date( Date.parse( birthday ) ).getFullYear(),\n      sortable: true,\n    },\n  ]\n}\n```\n\n![](docs-images/readme-example.png)\n\n### fetch()\n\n```TypeScript\nfetch: ( fetchArgs: FetchArgs, fetchOptions: FetchOptions, fetchReason: FetchReason ) =\u003e Promise\u003cPage\u003cT\u003e\u003e\n\ninterface FetchArgs {\n  /** 0-based page to fetch */\n  page: number,\n  /** Max number of items per page to fetch */\n  size: number,\n  /** Filter values filled by filter cells (by invoking onFilterByChange callback) */\n  filter?: Record\u003cstring, unknown\u003e;\n  /** Sort by field.\n  If multiple fields are specified sort done in order is from last to first.\n  (i.e. reversed before put in (for example) ORDER BY clause of SQL query) */\n  sort?: { field: string, direction?: 'ASC' | 'DESC' }[]\n}\n\n// Additional options to pass to fetch() implementation.\n// Can be just passed as fetch( ... , { ...fetchOptions, /* other options */ } )\ninterface FetchOptions {\n  // value of new AbortController().signal to pass to fetch\n  signal?: AbortSignal,\n}\n\nexport enum FetchReason {\n  FIRST_TIME_FETCH,\n  FETCH_ARGS_CHANGE,\n  REFRESH_REQUIRED,\n}\n\n/**\n* Structure of type is same as Spring Data Page type, thus server result\n* can be pass to PageTable without transformation.\n*/\ninterface Page\u003cT\u003e {\n  content: T[];\n  number: number;\n  totalElements: number;\n  totalPages: number;\n}\n```\nProvides a way to get items to display. User shall not think about bouncing/scheduling/etc,\njust provide data fetch implementation. `page` field is 0-based.\n\n### Header and footer customization\nFirst of all there are `headerRenderer` and `footerRenderer` props of `PageTable` that allow to override header and footer rendering completely. Default implementation uses ControlledContext (and yours can too) to get access to controllable component props (such as current page and others).\n\nAdditionally there is `headerElements` and `footerElements` props that allows to pass array of elements to be drawn in header and footer. This is array of lines, line is array of columns, column is array of component classes (functions) that shall be rendered in header and footer. Default values are:\n* For header: `[ [ [ VisibleFieldsButton, PageIndexSelector ], [ PageSizeSelector ] ] ]`\n* For footer: `[ [ [ VisibleFieldsButton, PageIndexSelector ], [ PageSizeSelector ] ], [ [ ActionsToolbar ] ] ]`\n\nParts of header and footer are exported as:\n* `DefaultFooter` and `DefaultHeader` -- default implementation of header and footer\n* `ActionsToolbar` -- action buttons toolbar (button toolbar)\n* `PageIndexSelector` -- pagination control\n* `PageSizeSelector` -- page size select control\n* `VisibleFieldsButton` -- button to show visible fields dialog\n\n### Utility functions\n\n#### fetchFromArray\n\nEmulates fetching data from provided array. Supports pagination and sorting (with strings and numbers).\n\n```TypeScript\nimport { fetchFromArray } from '@vlsergey/react-bootstrap-pagetable';\n\nasync function fetchFromArray\u003cT\u003e(\n    itemModel: ItemModel\u003cT\u003e,\n    src: T[],\n    fetchArgs: FetchArgs ): Promise\u003cPage\u003cT\u003e\u003e\n```\n\n#### fetchFromSpringDataRest\n\n```TypeScript\nimport { fetchFromSpringDataRest } from '@vlsergey/react-bootstrap-pagetable';\n\nasync function fetchFromSpringDataRest\u003cK extends string, T\u003e(\n  url: string,\n  fetchArgs: FetchArgs,\n  responseCollectionKey: K ): Promise\u003cPage\u003cT\u003e\u003e\n```\n\nFetches data from Spring Data REST API. Provided URL can be absolute or relative.\nFields keys to sort or to filter assumed to be passed to server without modifications.\nConvert \"virtual\" fields to server ones before providing `fetchArgs` to function.\n\n`responseCollectionKey` is the name of result collection element inside of `_embedded` structure in response.\n\n#### springDataRestResponseToPage\n\n```TypeScript\nimport { springDataRestResponseToPage } from '@vlsergey/react-bootstrap-pagetable';\n\ninterface SpringDataApiResponseType\u003cK extends string, T\u003e {\n  _embedded: {\n    [P in K]: T[];\n  };\n  page: {\n    size: number;\n    totalElements: number;\n    totalPages: number;\n    number: number;\n  };\n}\n\nfunction springDataRestResponseToPage\u003cK extends string, T\u003e(\n    key: K, response: SpringDataApiResponseType\u003cK, T\u003e\n): Page\u003cT\u003e\n```\n\nConverts Spring Data REST API response to Page structure expected by PageTable.\n`key` is the name of content collection in `_embedded` structure.\n\n[npm-image]: https://img.shields.io/npm/v/@vlsergey/react-bootstrap-pagetable.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/@vlsergey/react-bootstrap-pagetable\n[travis-image]: https://travis-ci.com/vlsergey/react-bootstrap-pagetable.svg?branch=master\n[travis-url]: https://travis-ci.com/vlsergey/react-bootstrap-pagetable\n[downloads-image]: http://img.shields.io/npm/dm/@vlsergey/react-bootstrap-pagetable.svg?style=flat-square\n[downloads-url]: https://npmjs.org/package/@vlsergey/react-bootstrap-pagetable\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvlsergey%2Freact-bootstrap-pagetable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvlsergey%2Freact-bootstrap-pagetable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvlsergey%2Freact-bootstrap-pagetable/lists"}