- Notifications
You must be signed in to change notification settings - Fork1
fdebef/Gridact
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Gridact is React component for displaying large datasets in table supporting
- filtering
- sorting
- paging
- custom page lengths with initial set
- custom row classes based on row data
- individual columns definitions
- column name
- sortable, editable,
- hidden, width, table head class
- custom cell rendering (based on cell and row data)
- custom cell class rendering based on row data
- inline editing with server side processing
- edit cells
- add and remove rows
- custom allowed values and characters
- error messages
##Live demo on CodeSandBox
Please open the project in window (https://89khh.codesandbox.io/), not in CodeSandBox browser, does not work.
##Changelog 3.1.0 (2022-08-18)
- optimized version, a lot of changes in code, coded splitted into more modules for better readability.
- added cross-application gridactContext, which made it much better administratable.
- primaryKey property no longer user, module calculates its own.
##Changelog 2.5.0
- new format of data from edit, simplier
{newValue, column, row}From Row you can find whatever identification you need.Remove primary_key property of GridAct - you do not need this anymore
##Changelog 2.1.0
- editable option in column definitions can now be function (e.g. you want to edit only if some condition is met)
- enhanced sorting, corrected sort of empty (null) values
- title option now available in columns definition
##Changelog 2.0.0
- Further optimized re-render evaluation on row (propsAreEqual.js)
- Code readability improved
- Access to filtered rows, so you can e.g. calculate total sums to your table header (look at setFilteredData prop)
##Changelog 1.0.0
- Many small bugs fixed
- Changed Icons to Font Awesome
- initial sort (initSort) now possible
- mainTableContainerClass for styling whole table container
I have done my best to optimize rendering, so the work is for user very good with rendering displayed tablewith 2000 cells (100 rows with 20 columns) in ~200 ms or 10000 cells in ~800 ms. (Change page to page render time.)Render speed is not very much affected with total size of data, but with data displayed. For user experienceI recommend not to allow page longer then 100 rows with 20 columns table.
Gridact component is result of my experience working with Microsoft Excel as an user andjQuery DataTables as developer. Datatables taught me to love datain JavaScript and that's a big thanks toAllan Jardine. This motivated me to create Gridact.
This is my first public React Component, I'll be really glad for any feedback and I'll do my bestto satisfy any of your requests. Thanks.
##ContactEmail me at filip (a) debef . com
Send me a Messenger message
Nothing but easy.npm i gridact
These modules must be installed in parent component.Bootstrap must be imported in whichever parent component.(Bootstrap removed in version 0.6.0)
For proper function of error messages, append<div></div> to yourbody ofindex.html.
The basic configuration is pretty simple. Just import Gridact module and pass data and some configuration:
importGridactfrom'gridact'importReactfrom'react';constApp=()=>{const[data,setData]=useState();useEffect(()=>{yourApi().then(yourData=>{setData(yourData)})},[])<Gridactdata={data}colDefs={tableColsDef}wrapperDivClass={['table-responsive','col-xl-12']}tableClasses={['table','table-sm','table-striped','text-nowrap','table-bordered']}pagingOptions={[5,10,20,50,100]}fnRowClass={(row)=>{if(row.name_original){if(row.name_original.includes('X'))return'font-weight-bold text-danger';returnundefined;}returnundefined;}}serverSideEdit={editData=>YourApi('yourUri',editData)}showFilteraddRemovepageSelectorpagingSelectorsearchPlaceHolder="Search..."onEnterMoveDown={false}/>
Type:Array of Objects<mandatory>
[{col1:val,col2:val,...},{col1:val,col2:val,...},...]
Type:Array, String<option>
Props is joined to final classNamesclassNames=wrapperDivClass.join(' ')
Final table is wrapped in div - main reason was enabling responsiveness in bootstraps, what requires table's outer div.For table responsiveness, use at least 'table-responsive col'
Type:Array | String<option>
Props is joined to final classNamesclassNames=wrapperDivClass.join(' ')
Best use with boostrap's table classes. E.g.['table', 'table-sm', 'table-striped', 'text-nowrap', 'table-bordered']
Type:String
Main container class, in this container is wrapped table and all controll items. (Paging, search,...)
###tableCellClass ###Type:String<option>
Easy cell styling, changes style ofth andtd cells in table.
###setFilteredData ###Type:Function<option>
Function will be passed with filtered datasetArray - subset of originaly provided table data.Necessary e.g. for sum of filtered columns.
Type:Array<option>
Page length options. Will always be sorted numerically, first value will be initials.
Example:[20,10,50,100] - paging options will be[10,20,50,100] - initial set will be[20].If undefined, default paging is[10, 20, 50].
Type:String | Array | function<option>
String or Array of classNames
If function is provided, it is passed row data. Must return String or Array.Used e.g. for coloring whole row based on row data.
Type:String | Array | function<option>
String or Array of classNames
If function is provided, it is passed row data. Must return String or Array.Used e.g. for coloring whole row based on row data.
Type:String | Array | function<option>
String or Array of classNames
If function is provided, it is passed row data. Must return String or Array.Used e.g. for coloring cells based on row data.
Type:Object <option>
Initial sort of table in object {col:colName, dir:'asc' | 'desc' }
AcceptedValues:function<mandatory> if editable columns
Function is provided with Object according to selected operation.
edit
Cell edit
Passed argument:{operation: 'edit', newValue: {[editedColumn]: [newValue]}, row: [rowData]}}
Required response: Promise resolved with{data: [updatedRow]}
If you want to validate data server-side, you can response with{error: errorMsg}, whereerrorMsg is string,which will be displayed in small overlay next to edited cell.
Iferror is in response, data will not be updated in table, previous value will be restored.
new
Add new row
Passed argument:{operation: 'new'}
Required response: Promise resolved with{data: [newRow]} In newRow, primary_key must not benull.
delete
Delete row, where is focused cell.
Passed argument:{operation: 'delete', row: [rowData]}
Required response:{data: 1}
If value ofdata key is < 1, row will not be deleted in table.
click
You can choose for clicking on cell value and change it on click.Passed argument:{operation: 'edit', newValue: {[editedColumn]: [oldValue]}, row: [rowData]}}
You decide, how the value should change on click.Response should be{data: [updatedRow]}
Type:Boolean <option>
Shows/hide filter (search field), add remove row buttons, page selector (what page is displayed),paging selector (page length)
Type:String<option>
Default: "Search..."
Type: Boolean
Iftrue, onenter cursor moves down. otherwise moves right.
Columns definitions
Type:Object<mandatory>
colDefs is object, where keys are column codes, values are column definitions itsels in Object.
{line_id:{cellRender:v=>v,name:'ID',editable:false,// filterEditValue: function | regexp of chars to filter out (newValue.prototype.replace(regexp, '')// function must return BooleanfilterEditValue:(newValue,curCellValue,row)=>(newValue.replace(/[{]|[}]|[<]|[>]|[\\]|[/]/g,'')),// filterEditValue: function which returns true to allow or false for disable char// regexp of chars allowed (newValue.prototype.match(regexp))filterEditChar:(char,cellValue,row)=>char.match(/[a-zA-ZščřžýáíéóúůďťňĎŇŤŠČŘŽÝÁÍÉÚŮ0-9]/g),sortable:true,filterable:true,resizable:true,width:80,hidden:false}},...}
Type: function | string<option>
If undefined, the cell is rendered with value provided in data.If string is provided, the string is returned.Function is passedcell_value androw_data. This means, you can render the cell based on other values in row.
Example:cellRender: (cellValue, rowData) => if (rowData.volume) > 10 return 'TOO HIGH' else return cellValue
Special attention on circular objects as cellRender:You can pass function returning React Components to cellRender (e.g.input select in table head). As GridAct useson row level custom property change evalution (React.memo, or formerly known as ComponentShouldUpdate), if you passin cellRender circular objects other then React Component , application with crash. For common use this should notlimit you.
Type: string<mandatory>
Name of column in table header
Type: integer<option>
Set width of current column. Default<td> css style isoverflow: hidden.
Type:Boolean | Function(cellValue, rowData) <option>
Column cells will be editable. If value is not Boolean or Function, it is evaluated as Boolean(providedValue)
Type:Boolean <option>
Column cells will be sortable. If
Type: Boolean<option>
Column will be hidden. Usefull when you want to calculate cell value from multiple columns or style cell based on datafrom other columns but the other columns you do not want to show.
Type:Boolean | Function(cellValue, rowData) <option>
Title (small hint over cell), e.g. when not whole content is visible, or when you want to comment the cell content.Default is false, when set toTrue, the content of cell is used.
Type:String | Array | function<option>
Class used for every cell in this column.
String or Array of classNames
If function is provided, it is passed(cellValue, rowData). Must return String or Array.Used e.g. for coloring whole column based on data of given cell or other cells in row.
Type:String | Array | function<option>
Class used for every cell in this column.
String or Array of classNames
If function is provided, it is passed(cellValue, rowData). Must return String or Array.Used e.g. for coloring whole column based on data of given cell or other cells in row.
As the inline edit is build upon contentEditable, I paid a lot of attention to sanitize input text to avoid XSS.There two filter options for values users can write to cell.
Type:RegExp | function<optional>
This option is applied directly onKeyPress event - it does not let user write the characters you specify.If RegExp is provided, it is passed tocharacter_typed.match().Function is passed three arguments:(character_typed, cell_value_before_edit, row_data) Must returntrue orfalse.True = character is allowed, false = disallowed.Default value is(char, CellValue, rowData) => return char.match(/[a-zA-ZščřžýáíéóúůďťňĎŇŤŠČŘŽÝÁÍÉÚŮ0-9 ]/);Allowed are only alphanumeric characters included Czech ones.
Type:RegExp | function<optional>
Because above mentioned option does not block pasting from clipboard, and I didn't want to forbid it generally,we have to check the final value user sends to your serverSideEdit function and which will be displayed in table.As this is potential XSS risc, pay close attention to this function.Function is passed three arguments:(new_cell_value, cell_value_before_edit, row_data) Must return sanitized string.Default value is(newValue, cellValue, row) => (newValue.replace(/[{]|[}]|[<]|[>]|[\\]|[/]/g, ''))
If RegExp is provided, it is passed tonewValue.replace(RegExp, '')
You can fully style with own classes. See customstyles.css. GridAct is built on CSS grid.
I'll be glad if you leave me a message. What you miss, what you want, what you like.What can be added in the future:
- customizable icons
- custom placement of Search, add / remove buttons and paging options.
- better page selector
About
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Uh oh!
There was an error while loading.Please reload this page.
