UNPKG

yii-react-gridview

Version:
177 lines (163 loc) 9.26 kB
# Yii2 GridView widget for react This component is created to simplify moving from php rendering of built-in [Yii2 Gridview widget](https://www.yiiframework.com/doc/api/2.0/yii-grid-gridview) to React-based application using some of its familiar settings. [Simple example](https://codepen.io/sufitman/project/editor/XVamYV) ## Installing ```bash npm install --save yii-react-gridview ``` ## Setting `props` Instead of using `pager` or `dataProvider` objects as it used in [Yii2 Gridview widget](https://www.yiiframework.com/doc/api/2.0/yii-grid-gridview), some of its properties (or equivalents) should be set as props directly in GridView component. It makes more suitable way for React of re-rendering the component in case if some prop will be changed. See [Available props](#available-props) to find out how to set up your GridView. ## Example of component: ```jsx import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import GridView from 'yii-react-gridview'; import Axios from 'axios'; class App extends Component { constructor (props) { super(props); this.state = { data: null, }; Axios.get('/your/get-data').then(response => { let dataProvider = response.data; this.pageSize = dataProvider.pageSize; this.headerCells = dataProvider.headerCells; this.maxButtonCount = dataProvider.maxButtonCount; this.setState({ data: dataProvider.data, currentPage: dataProvider.currentPage, totalCount: dataProvider.totalCount, }); }); this.columns = { username: null, email: null, city: null, } } onPageButtonClicked = (currentPage) => { Axios.get('/your/get-data').then(response => { this.setState({ currentPage: currentPage, //... }); }) }; onSortChanged = (sort) => { this.setState({sort: sort}); Axios.get('/your/get-data', { params: { // Pass 'sort' as is (js-object) or prepare it to be compatible with Query::orderBy() orderBy: sort, //... } }).then(response => { this.setState({ //... }); }); }; render() { return ( <div className="App"> <GridView data={ this.state.data } headerCells={ this.headerCells } columns={ this.columns } currentPage={ this.state.currentPage } totalCount={this.state.totalCount} maxButtonCount={ this.maxButtonCount } pageSize={this.pageSize } onPageButtonClick={ this.onPageButtonClicked } onSortChange={ this.onSortChanged } /> </div> ); } } ReactDOM.render(<App/>, document.getElementById('root')); ``` of action: ```php class YourController extends Controller { public function actionGetData($currentPage = 0, $pageSize = 20, $filters = [], $orderBy = '') { \Yii::$app->response->format = Response::FORMAT_JSON; // Prepare orderBy object here or do it in 'onSortChange' callback // Anyway make it compatible with '->orderBy($orderBy)' $preparedOrderBy = []; if ($orderBy) { foreach (Json::decode($orderBy) as $col => $sort) { $preparedOrderBy[] = "{$col} {$sort}"; } if (!empty($preparedOrderBy)) { $preparedOrderBy = implode(',', $preparedOrderBy); } } // Probably $filters should be also prepared // ... return [ 'data' => ArrayHelper::toArray(User::find() ->andFilterWhere($filters) ->offset($currentPage * $pageSize) ->orderBy($preparedOrderBy) ->limit($pageSize) ->all(), [ User::class => [ 'username', 'email', 'city', ] ]), 'headerCells' => (new User)->attributeLabels(), 'currentPage' => (int) $currentPage, 'totalCount' => (int) User::find()->andFilterWhere($filters)->count(), 'pageSize' => $pageSize, ]; } } ``` ## Available `props` |Property|Type|Default value|Description| |:---:|:---:|:---:|:---| |`data`|Array|undefined|Array of models to show in list| |`notSetText`|string|'(not set)'|Text will be shown when a cell in a row is not set| |`headerCells`|Object|{}|Key-value pairs of names of data models properties. It should contain the same keys as keys of an Object in `data`.<br>Values of `headerCells` could be either strings or object of following structure: <br>` { value: 'Column Title', column: 'attrbute_name', enableSorting: true, sort: 'ASC' }`.<br>If `enableSorting` is `true` then `column` required. `sort` (if specified) must be either 'ASC' or 'DESC'| |`footerCells`|Array|[]|Array of strings or components corresponding cells of `tfoot`-row. Make sure the array length match the table| |`caption`|String|undefined|A string for caption if necessary| |`emptyCaption`|String|'Nothing found'|The text will be shown when no data rows are loaded| |`captionOptions`|Object|{}|HTML attributes of `caption`| |`containerOptions`|Object|{}|HTML attributes of GridView instance conteiner (div that wraping the table and the pager)| |`tableOptions`|Object|{}|HTML attributes of table| |`showHeader`|Boolean|true|Whether show \<thead\> or not| |`showFooter`|Boolean|false|Whether show \<tfoot\> or not| |`hidePager`|Boolean|false|Whether show pager buttons or not| |`placeFooterAfterBody`|Boolean|true|Whether place \<tfoot\> after body or not| |`headerRowOptions`|Object|{}|HTML attributes of *thead > row*| |`footerRowOptions`|Object|{}|HTML attributes of *tfoot > row*| |`rowOptions`|Object|{}|HTML attributes of *tbody \> row*| |`columns`|Object|undefined|Keys of the object are whether properties of a model in data (then the title will be provided by `headerCells`) or custom strings that will be a column titles.<br>Values of the object are either null (to provide a model value as is) or `function (cell, rowId, hoveredRowId)` (to decorate a model value with its result).<br>Also string `'serial'` can be set to provide models numeration.<br>If `'checkbox'` is set as a key and its value (just value at least) then column of checkboxes will be rendered in order to select row(s) ids (a value that specified in `rowIdColumn`)| |`filters`|Object|null|Contain *filters* for specified columns. *Filters* can be:<br>a) string `'text'` renders simple input of `type="text"`;<br>b) Object `{ type: ..., options: {...} }` where type can be either `'text'` (input of `type="text"`), `'checkbox'` or `'select'`. Options typically are HTML attributes of the inputs. If type is `'select'` then `options` should contain `data` - object of options (where key is value attribute of an \<option\> and value is its text);<br>c) `function (name, onChange)` to render custom input with name={ `name` } and onChange={ `onChange` } (must return a React.Component/html) | |`onSortChange`|`function(sort)`|undefined|Callback to sort the data with `sort` - key-value object (```js { column:'ASC' /* or 'DESC' */ }```) to sort the `data`. The way of is up to you| |`onFilterChange`|`function(filters)`|undefined|Callback to filter the data with `filters` - key-value object to filter the `data`. **Required** when filters are specified. The way of filtering depends on you| |`pagerOptions`|object|undefined|HTML attributes of pager container| |`currentPage`|integer|undefined|Number of current page (begins from 0). **Should be provided by `data` provider**| |`totalCount`|integer|undefined|Total count of models given in `data`. **Should be provided by `data` provider**| |`maxButtonCount`|integer|10|Max count of pager links| |`pageSize`|integer|20|Max count of models on a page| |`pagerTag`|string|`'ul'`|Tag name of pager container| |`pageTag`|string|`'li'`|Tag name of pager link| |`activePageCssClass`|string|`'active'`|Class name of active page link| |`disabledPageCssClass`|string|`'disabled'`|Class name of disabled pager link| |`nextPageCssClass`|string|`'next'`|Class name of 'next' page link| |`prevPageCssClass`|string|`'prev'`|Class name of 'previous' page link| |`firstPageCssClass`|string|`'first'`|Class name of 'first' page link| |`lastPageCssClass`|string|`'last'`|Class name of 'last' page link| |`nextPageLabel`|string|`'»'`|Label of 'next' page link| |`prevPageLabel`|string|`'«'`|Label of 'previous' page link| |`firstPageLabel`|string|null|Label of 'first' page link| |`lastPageLabel`|string|null|Label of 'last' page link| |`onPageButtonClick`|`function(pageNumber)`|null|Callback of click on pager link with given page number. Originally it should replace `pageNumber` with its page number and reload the `data`, but it's up to you whatever it does.| |`onSelectionChange`|`function(selectedRowIds)`|null|Callback which will be applied when a row is (or all rows are) selected. Array of selected values specified in `rowIdColumn` will be passed in `selectedRowIds`| |`rowIdColumn`|string|'id'|Column name that could be used as primary key for selection. If `onSelectionChange` is set, then array of values of selected rowIdColumn will be passed as an argument|