{"id":29284871,"url":"https://github.com/hellosebastian/react-table-bundle","last_synced_at":"2025-10-16T20:08:53.615Z","repository":{"id":62515699,"uuid":"323131084","full_name":"HelloSebastian/react-table-bundle","owner":"HelloSebastian","description":"Symfony Bundle for React Table configuration in PHP.","archived":false,"fork":false,"pushed_at":"2021-01-12T16:53:26.000Z","size":934,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-05T22:01:55.878Z","etag":null,"topics":["bundle","react-table","symfony"],"latest_commit_sha":null,"homepage":"","language":"PHP","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/HelloSebastian.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":"2020-12-20T17:49:18.000Z","updated_at":"2021-01-12T16:51:29.000Z","dependencies_parsed_at":"2022-11-02T10:30:58.410Z","dependency_job_id":null,"html_url":"https://github.com/HelloSebastian/react-table-bundle","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/HelloSebastian/react-table-bundle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloSebastian%2Freact-table-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloSebastian%2Freact-table-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloSebastian%2Freact-table-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloSebastian%2Freact-table-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HelloSebastian","download_url":"https://codeload.github.com/HelloSebastian/react-table-bundle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloSebastian%2Freact-table-bundle/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263813814,"owners_count":23515344,"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":["bundle","react-table","symfony"],"created_at":"2025-07-05T22:01:52.060Z","updated_at":"2025-10-16T20:08:53.527Z","avatar_url":"https://github.com/HelloSebastian.png","language":"PHP","readme":"# ReactTableBundle\n\n**This Bundle provides *simple* [react-table](https://github.com/tannerlinsley/react-table/tree/v6) configuration for your Doctrine Entities.** With the option to create your own columns in JavaScript.\n\nReactTableBundle uses React Table v6. (React Table v7 is headless, means no CSS and layout. I'm not a CSS expert, \nso I'm still using v6 at the moment. Once a flex layout for v7 is ready, the bundle can be easily adapted, since the \nAPI for the columns is very similar.)\n\nHighly inspired by [SgDatatablesBundle](https://github.com/stwe/DatatablesBundle).\n\n**The project is currently still under development. It can not be excluded that configuration changes.**\n\n\n\n## When should I not use ReactTableBundle\n\nReactTableBundle is designed for simple tables that are strongly bound to the entities. If you are creating highly customized tables with many components and a lot of client-side programming, ReactTableBundle is not suitable for that. However, you can of course use ReactTableBundle alongside your complex tables.\n\n\n\n## Overview\n\n1. [Features](#features)\n2. [Installation](#installation)\n3. [Your First Table](#your-first-table)\n4. [Columns](#columns)\n5. [Table Props Configuration](#table-props)\n6. [Persistence Options Configuration](#persistence-options)\n\n\n## Features\n\n* Table Configuration in PHP\n* Filtering*\n* Sorting*\n* Pagination*\n* Persist table state (sorting, filtering, current page, ...) in cookies\n* Column Types: [TextColumn](#textcolumn), [BooleanColumn](#booleancolumn), [DateTimeColumn](#datetimecolumn), [ActionColumn](#actioncolumn)\n* Custom Columns with [OwnColumn](#owncolumn)\n\n*server-side\n\n## Installation\n\n### Step 1: Download the Bundle\n\nOpen a command console, enter your project directory and execute the following command to download this bundle:\n\n``` bash\n$ composer require hello-sebastian/react-table-bundle\n```\n\n\n\n### Step 2: Enable the Bundle (without flex)\n\nThen, enable the bundle by adding it to the list of registered bundles in the `config/bundles.php` file of your project:\n\n``` php\n// config/bundles.php\n\nreturn [\n    // ...\n    HelloSebastian\\ReactTableBundle\\ReactTableBundle::class =\u003e ['all' =\u003e true],\n];\n```\n\n\n### Step 3: Assetic Configuration\n\n#### Install the web assets\n\n``` bash\n# if possible, make absolute symlinks (best practice) in public/ if not, make a hard copy\n\n$ php bin/console assets:install --symlink\n```\n\n``` bash\n# make a hard copy of assets in public/\n\n$ php bin/console assets:install\n```\n\n#### Add Assets into your base.html.twig\n\n``` html\n\u003clink rel=\"stylesheet\" href=\"{{ asset('bundles/reacttable/app.css') }}\"\u003e\n\u003cscript src=\"{{ asset('bundles/reacttable/app.js') }}\"\u003e\u003c/script\u003e\n```\n\n\n\n## Your First Table\n\n### Step 1: Create a ReactTable class\n\n\n``` php\n// src/ReactTable/UserTable.php\n\n\u003c?php\n\nnamespace App\\ReactTable;\n\nuse App\\Entity\\User;\nuse HelloSebastian\\ReactTableBundle\\Columns\\ActionColumn;\nuse HelloSebastian\\ReactTableBundle\\Columns\\BooleanColumn;\nuse HelloSebastian\\ReactTableBundle\\Columns\\ColumnBuilder;\nuse HelloSebastian\\ReactTableBundle\\Columns\\DateTimeColumn;\nuse HelloSebastian\\ReactTableBundle\\Columns\\TextColumn;\nuse HelloSebastian\\ReactTableBundle\\Data\\ActionButton;\nuse HelloSebastian\\ReactTableBundle\\Filter\\SelectFilter;\nuse HelloSebastian\\ReactTableBundle\\ReactTable;\n\nclass UserTable extends ReactTable\n{\n    /**\n     * @inheritDoc\n     */\n    protected function buildColumns(ColumnBuilder $builder)\n    {\n        $columnBuilder\n            -\u003eadd('username', TextColumn::class, array(\n                'Header' =\u003e 'Username'\n            ))\n            -\u003eadd('email', TextColumn::class, array(\n                'Header' =\u003e 'E-Mail',\n                'show' =\u003e false\n            ))\n            -\u003eadd('firstName', TextColumn::class, array(\n                'Header' =\u003e 'First name'\n            ))\n            -\u003eadd('lastName', TextColumn::class, array(\n                'Header' =\u003e 'Last name'\n            ))\n            -\u003eadd('createdAt', DateTimeColumn::class, array(\n                'Header' =\u003e 'Created at',\n                'format' =\u003e 'd.m.Y'\n            ))\n            -\u003eadd('department.name', TextColumn::class, array(\n                'Header' =\u003e 'Department',\n                'emptyData' =\u003e 'No Department',\n                'filter' =\u003e array(SelectFilter::class, array(\n                    'choices' =\u003e array(\n                        'IT' =\u003e 'IT',\n                        'Sales' =\u003e 'Sales'\n                    )\n                ))\n            ))\n            -\u003eadd('department.costCentre.name', TextColumn::class, array(\n                'Header' =\u003e 'Cost Centre',\n                'emptyData' =\u003e 'No Cost Centre',\n                'filter' =\u003e array(SelectFilter::class, array(\n                    'choices' =\u003e array(\n                        '001' =\u003e '001',\n                        '002' =\u003e '002',\n                      \t'null' =\u003e 'empty'\n                    )\n                ))\n            ))\n            -\u003eadd('isActive', BooleanColumn::class, array(\n                'Header' =\u003e 'is active',\n                'trueValue' =\u003e 'yes'\n            ))\n            -\u003eadd(null, ActionColumn::class, array(\n                'Header' =\u003e 'Actions',\n                'width' =\u003e 120,\n                'buttons' =\u003e array(\n                    array(\n                        'displayName' =\u003e 'show',\n                        'routeName' =\u003e 'show_user',\n                        'additionalClassNames' =\u003e 'btn-success'\n                    ),\n                    array(\n                        'displayName' =\u003e 'edit',\n                        'routeName' =\u003e 'edit_user'\n                    )\n                )\n            ));\n    }\n\n    protected function getEntityClass(): string\n    {\n        return User::class;\n    }\n}\n```\n\n\n### Step 2: In the Controller\n\n``` php\n// src/Controller/UserController.php\n\n// ...\nuse HelloSebastian\\ReactTableBundle\\ReactTableFactory;\n// ...\n\n/**\n * @Route(\"/\", name=\"default\")\n */\npublic function index(Request $request, ReactTableFactory $reactTableFactory) : Response\n{\n    $table = $reactTableFactory-\u003ecreate(UserTable::class);\n\n    $table-\u003ehandleRequest($request);\n    if ($table-\u003eisCallback()) {\n        return $table-\u003egetResponse();\n    }\n\n    return $this-\u003erender('index.html.twig', array(\n        'table' =\u003e $table-\u003ecreateView()\n    ));\n}\n```\n\n### Step 3: Add table in Template\n\n``` html\n{% extends 'base.html.twig' %}\n\n{% block body %}\n    \u003cdiv class=\"react-table-bundle\" data-table=\"{{ table }}\"\u003e\u003c/div\u003e\n{% endblock %}\n```\n\n\n\n## Columns\n\n### TextColumn\n\nRepresents column with text.\n\n#### Options\n\n| Option          | Type           | Default                      | Description                                                  |\n| --------------- | -------------- | ---------------------------- | ------------------------------------------------------------ |\n| Header          | string         | \"\"                           | set colum header                                             |\n| width           | integer / null | null                         | width in px for column                                       |\n| filterable      | bool           | true                         | enable / disable filtering for this column                   |\n| sortable        | bool           | true                         | enable / disable sortable for this column                    |\n| resizable       | bool           | true                         | enable / disable resizable for this column                   |\n| show            | bool           | true                         | show / hide column                                           |\n| className       | string         | \"\"                           | set the classname of the `td` element of the column          |\n| headerClassName | string         | \"\"                           | set the classname of the `th` element of the column          |\n| footerClassName | string         | \"\"                           | set the classname of the `td` element of the column's footer |\n| filter          | array / null   | [TextFilter::class, array()] | first element in array is a filter class, second element is a configuration array for the filter class (see Filters) |\n| emptyData       | string         | \"\"                           | default value if attribute from entity is null               |\n| sortQuery       | Closure / null | null                         | custom sort query                                            |\n| dataCallback    | Closure / null | null                         | custom data callback                                         |\n\n#### Example\n\n```php\n-\u003eadd('username', TextColumn::class, array(\n    'Header' =\u003e 'Username',\n  \t'emptyData' =\u003e \"No Username found.\",\n  \n    //optional overrides ...\n  \t'dataCallback' =\u003e function (User $user) { //entity class from getEntityClass\n        //you can return what ever you want ... but only string or number  \n        return $user-\u003egetId() . \" \" . $user-\u003egetUsername();\n    },\n  \t'sortQuery' =\u003e function (QueryBuilder $qb, $direction) {\n        $qb-\u003eaddOrderBy('username', $direction);\n    },\n  \t'filter' =\u003e array(TextFilter::class, array(\n    \t'placeholder' =\u003e 'Search ...',\n      \t'filterQuery' =\u003e function (QueryBuilder $qb, $field, $value) {\n            //add custom expressions to QueryBuilder ...\n          \t//field = \"username\"\n          \t//value = text from filter\n        }\n    ))\n))\n```\n\n\n\n### BooleanColumn\n\nRepresents column with boolean values.\n\n#### Options\n\nAll options of TextColumn\n\nThe option `filter` is set to `SelectFilter` by default.\n\n**And**:\n\n| Option     | Type   | Default | Description            |\n| ---------- | ------ | ------- | ---------------------- |\n| trueLabel  | string | \"True\"  | label for true values  |\n| falseLabel | string | \"False\" | label for false values |\n\n#### Example\n\n```php\n-\u003eadd('isActive', BooleanColumn::class, array(\n    'Header' =\u003e 'is active',\n    'trueLabel' =\u003e 'yes',\n    'falseLabel' =\u003e 'no'\n))\n```\n\n\n\n### DateTimeColumn\n\nRepresents column with DateType values.\n\n#### Options\n\nAll Options of TextColumn\n\n**And:**\n\n| Option | Type   | Default       | Description            |\n| ------ | ------ | ------------- | ---------------------- |\n| format | string | \"Y-m-d H:i:s\" | DateTime format string |\n\n#### Example\n\n```php\n-\u003eadd('createdAt', DateTimeColumn::class, array(\n    'Header' =\u003e 'Created at',\n    'format' =\u003e 'd.m.Y'\n))\n```\n\n\n\n### OwnColumn\n\nWith OwnColumn you can provided custom data und JavaScript configuration to the table. E.g. you can create a Image or Link column with OwnColumn.\n\n#### Options\n\nAll Options of TextColumn.\n\n`sortable` and `filterable` are disabled by default. If you want to enable that you must provide custom `sortQuery` and `filter` with `filterQuery`.\n\n`dataCallback`  is required.\n\n#### Example\n\n**Table configuration in PHP**\n\n```php\n-\u003eadd(\"custom\", OwnColumn::class, array(\n    'Header' =\u003e 'My Column',\n    'dataCallback' =\u003e function (User $user) {\n        return \"Hello\";\n    },\n    'sortQuery' =\u003e function (QueryBuilder $qb, $direction) {\n      \t\n    }\n))\n```\n\n**Extend table configuration in JavaScript**\n\nIn your `base.html.twig` **before**  you include the bundle JS file you can listen to the custom event `rtb:componentDidMount`. Inside the event you can access the array of JavaScript column objects.\n\n```javascript\n\ndocument.addEventListener(\"rtb:componentDidMount\", function (e) {\n  e.detail.persistenceOptions.filtered = false; //see Persistence Options\n\n  //loop over all columns and filter by type \"own\". If you have multiply OwnColumns you must extend the filtering\n  \n  //Then you can set and access all provided attributes by react-table. E.g. React Cell, Footer, Header, Filter - components ...\n  \n  e.detail.columns.forEach(col =\u003e {\n    if (col.type === \"own\") {\n      col.Header = \"Custom Column\";\n      col.show = true;\n\n      col.Cell = (row) =\u003e { //row is provided by react-table\n        //if you import React you can render a customer component here as well.\n        // return \u003cMyCell row={row} /\u003e;\n        return row.original.username;\n      }\n    }\n  });\n});\n        \n```\n\n\n\n### ActionColumn\n\nRepresents column for action buttons (show / edit / remove ...).\n\n#### Options\n\nAll Options of TextColumn\n\n`sortable` and `filterable` are disable by default.\n\n**And:**\n\n| Option  | Type  | Default | Description                              |\n| ------- | ----- | ------- | ---------------------------------------- |\n| buttons | array | []      | array of buttons configuration as array. |\n\n#### Example\n\n```php\n-\u003eadd(null, ActionColumn::class, array(\n    'Header' =\u003e 'Actions',\n    'width' =\u003e 120, //optional\n    'buttons' =\u003e array(\n        array(\n            'displayName' =\u003e 'show',\n            'routeName' =\u003e 'show_user',\n            'additionalClassNames' =\u003e 'btn-success'\n        ),\n        array(\n            'displayName' =\u003e 'edit',\n            'routeName' =\u003e 'edit_user',\n            'additionalClassNames' =\u003e 'btn-success'\n       )\n  \t)\n))\n```\n\n#### ActionButtons\n\n| Option               | Type   | Default     | Description                                                  |\n| -------------------- | ------ | ----------- | ------------------------------------------------------------ |\n| displayName          | string | \"\"          | label of button in table                                     |\n| routeName            | string | \"\"          | route name                                                   |\n| routeParams          | array  | array(\"id\") | Array of property value names for the route parameters. By default is `id` set. |\n| classNames           | string | \"\"          | CSS class names which added directly to the `a` element. Overrides default class names from YAML config. |\n| additionalClassNames | string | \"\"          | You can set default class names in YAML config. Then you can add additional class names to the button without override the default config. |\n\n**YAML Config**\n\n```yaml\n# config/packages/react_table.yaml\n\nreact_table:\n\t# other configuration ...\n\tdefault_column_options:\n        action_column:\n            default_class_names: 'btn btn-xs'\n```\n\n\n\n## Configuration\n\n\n### Table Props\n\nTable Props are provided directly to ReactTable and are a collection of setting options for the table.\n\n#### Options\n\n| Option                        | Type    | Default                  |\n|-------------------------------|---------|--------------------------|\n| showPagination                | bool    | true                     |\n| showPaginationTop             | bool    | false                    |\n| showPaginationBottom          | bool    | true                     |\n| showPageSizeOptions           | bool    | true                     |\n| pageSizeOptions               | array   | [5, 10, 20, 25, 50, 100] |\n| defaultPageSize               | int     | 20                       |\n| showPageJump                  | bool    | true                     |\n| collapseOnSortingChange       | bool    | true                     |\n| collapseOnPageChange          | bool    | true                     |\n| collapseOnDataChange          | bool    | true                     |\n| freezeWhenExpanded            | bool    | false                    |\n| sortable                      | bool    | true                     |\n| multiSort                     | bool    | true                     |\n| resizable                     | bool    | true                     |\n| filterable                    | bool    | true                     |\n| defaultSortDesc               | bool    | false                    |\n| className                     | string  | ''                       |\n| previousText                  | string  | 'Previous'               |\n| nextText                      | string  | 'Next'                   |\n| loadingText                   | string  | 'Loading...'             |\n| noDataText                    | string  | 'No rows found'          |\n| pageText                      | string  | 'Page'                   |\n| ofText                        | string  | 'of'                     |\n| rowsText                      | string  | 'Rows'                   |\n| pageJumpText                  | string  | 'jump to page'           |\n| rowsSelectorText              | string  | 'rows per page'          |\n\n\nYou can either perform settings for all tables via a YAML file or set each individual table\n\n#### YAML-Configuration\n\n```yaml\n// config/packages/react_table.yaml\n\nreact_table:\n    default_table_props:\n        className: \"-striped -highlight\"\n        sortable: false\n```\n\n#### PHP-Configuration\n\nInside from Table class:\n\n``` php\n// src/ReactTable/UserTable.php\n\nclass UserTable extends ReactTable\n{\n    ...\n\n    public function configureTableProps(OptionsResolver $resolver)\n    {\n        parent::configureTableProps($resolver);\n    \n        $resolver-\u003esetDefaults(array(\n            'defaultPageSize' =\u003e 10\n        ));\n    }\n}\n```\n\n\nOutside from Table class:\n\n``` php\n// src/Controller/UserController.php\n\npublic function index(Request $request, ReactTableFactory $reactTableFactory) : Response\n{\n    $table = $reactTableFactory-\u003ecreate(UserTable::class);\n\n    $table-\u003esetTableProps(array(\n        'defaultPageSize' =\u003e 10\n    ));\n\n    ...\n}\n```\n\n\nIn the `configureTableProps` method, you can specify custom data that can be provided directly to the ReactTable.\n\n### Persistence Options\n\n#### Options\n\nWith the Persistence Options you can set which settings (filtering, sorting, current page, ...) should be stored in the cookies. By default, all of them are activated.\n\n| Option         | Type    | Default  |\n|----------------|---------|----------|\n| resized        | bool    | true     |\n| filtered       | bool    | true     |\n| sorted         | bool    | true     |\n| page           | bool    | true     |\n| page_size      | bool    | true     |\n\n#### YAML-Configuration\n\n```yaml\n// config/packages/react_table.yaml\nreact_table:\n    default_persistence_options:\n        sorted: true\n```\n\n\n#### PHP-Configuration\n\nInside from Table class:\n\n``` php\n// src/ReactTable/UserTable.php\n\nclass UserTable extends ReactTable\n{\n    ...\n\n    public function configurePersistenceOptions(OptionsResolver $resolver)\n    {\n        parent::configurePersistenceOptions($resolver);\n\n        $resolver-\u003esetDefaults(array(\n            'sorted' =\u003e false\n        ));\n    }\n}\n```\n\n\nOutside from Table class:\n\n``` php\n// src/Controller/UserController.php\n\npublic function index(Request $request, ReactTableFactory $reactTableFactory) : Response\n{\n    $table = $reactTableFactory-\u003ecreate(UserTable::class);\n\n    $table-\u003esetPersistenceOptions(array(\n        'page' =\u003e true\n    ));\n\n    ...\n}\n```\n\n\n\n## ToDo's\n* Documentation\n  * More Examples\n* Twig extension to render `div` element\n* Tests\n  * Unit Tests\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellosebastian%2Freact-table-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhellosebastian%2Freact-table-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellosebastian%2Freact-table-bundle/lists"}