superior-react-table
Version:
A superior table component for react
376 lines (350 loc) • 12.9 kB
Markdown
# Superior React Table
A multilanguage, editable, addable, removable, sortable, detailed searchable, responsive table component for react.
## Installation
```sh
npm install superior-react-table
```
## Live Demo
[https://halidunal.github.io > Portfolio > Superior React Table](https://halidunal.github.io)
## Example Code
``` js
import React, { useState } from 'react'
import Table from 'superior-react-table';
import { openModal } from '../../store/services/modalService';
export default function Index(){
const [editSelectedId,setEditSelectedId] = useState(0);
const [customers, setCustomers] = useState<ICustomer[]>(
[
{
"id": 1,
"last_name": "Doe",
"first_name": "John",
"email_address": "john@john.mail",
"job_title": "Purchasing Manager",
"is_active": false,
"mobile_phone": "(123)555-0103",
"profession_code": 345,
"birthday": "1981-06-11",
"city": "New Jersey",
"gross_salary": "6000$+"
},
{
"id": 2,
"last_name": "Gratacos Solsona",
"first_name": "Antonio",
"email_address": "antonio@antonio.mail",
"job_title": "Owner",
"is_active": true,
"mobile_phone": "(123)555-0101",
"profession_code": 555,
"birthday": "1989-09-29",
"city": "Boston",
"gross_salary": "-2000$"
},
{
"id": 3,
"last_name": "Axen",
"first_name": "Thomas",
"email_address": "thomas@thomas.mail",
"job_title": "Purchasing Representative",
"is_active": false,
"mobile_phone": "(123)555-0101",
"birthday": "1976-06-25",
"city": "Los Angelas",
"gross_salary": "4000-6000$"
},
{
"id": 4,
"last_name": "Lee",
"first_name": "Christina",
"email_address": "christina@christina.mail",
"job_title": "Purchasing Manager",
"is_active": true,
"mobile_phone": "(123)555-0101",
"profession_code": 101,
"birthday": "1993-01-15",
"city": "New York",
"gross_salary": "4000-6000$"
},
{
"id": 5,
"last_name": "O’Donnell",
"first_name": "Martin",
"email_address": "martin@marting.mail",
"job_title": "Owner",
"is_active": true,
"mobile_phone": "(123)555-0101",
"profession_code": 222,
"birthday": "1999-11-11",
"city": "Minneapolis",
"gross_salary": "2000-4000$"
},
{
"id": 6,
"last_name": "Pérez-Olaeta",
"first_name": "Francisco",
"email_address": "francisco@francisco.mail",
"job_title": "Purchasing Manager",
"is_active": false,
"mobile_phone": "(123)555-0100",
"profession_code": 333,
"birthday": "1992-11-01",
"city": "Milwaukee",
"gross_salary": "4000-6000$"
},
{
"id": 7,
"last_name": "Xie",
"first_name": "Ming-Yang",
"email_address": "ming@ming.mail",
"job_title": "Owner",
"is_active": true,
"mobile_phone": "(123)555-0100",
"birthday": "1997-12-10",
"city": "Boise",
"gross_salary": "4000-6000$"
},
{
"id": 8,
"last_name": "Andersen",
"first_name": "Elizabeth",
"email_address": "elizabeth@elizabeth.mail",
"job_title": "Purchasing Representative",
"is_active": true,
"mobile_phone": "(123)555-0100",
"profession_code": 444,
"birthday": "2001-12-30",
"city": "Portland",
"gross_salary": "4000-6000$"
},
{
"id": 9,
"last_name": "Mortensen",
"first_name": "Sven",
"email_address": "sven@sven.mail",
"job_title": "Purchasing Manager",
"is_active": false,
"mobile_phone": "(123)555-0101",
"profession_code": 555,
"birthday": "1989-05-02",
"city": "Salt Lake City",
"gross_salary": "2000-4000$"
},
{
"id": 10,
"last_name": "Wacker",
"first_name": "Roland",
"email_address": "roland@roland.mail",
"job_title": "Purchasing Manager",
"is_active": false,
"mobile_phone": "(123)555-0101",
"profession_code": 123,
"birthday": "1990-04-20",
"city": "Chicago",
"gross_salary": "-2000$"
},
{
"id": 11,
"last_name": "Krschne",
"first_name": "Peter",
"email_address": "peter@peter.mail",
"job_title": "Purchasing Manager",
"is_active": true,
"mobile_phone": "(123)555-0101",
"profession_code": 444,
"birthday": "1996-04-09",
"city": "Miami",
"gross_salary": "6000$+"
},
{
"id": 12,
"last_name": "Edwards",
"first_name": "John",
"email_address": "john@john.mail",
"job_title": "Purchasing Manager",
"is_active": false,
"mobile_phone": "(123)555-0101",
"profession_code": 123,
"birthday": "1995-03-19",
"city": "Las Vegas",
"gross_salary": "6000$+"
}
]
);
interface ICustomer {
id?: any,
last_name?: string,
first_name?: string,
email_address?: string,
job_title?: string,
is_active?: boolean,
mobile_phone?: string,
profession_code?: number,
birthday?: string,
city?: string,
gross_salary?: string
}
const [editRowData, setEditRowData] = useState<ICustomer>({
last_name: "",
first_name: "",
email_address: "",
job_title: "",
is_active: true,
mobile_phone: "",
profession_code: 0,
birthday: "",
city: "",
gross_salary: ""
});
const handleEditRowChange = (event: any) => {
var fieldName = event.target.getAttribute("name");
var fieldValue = event.target.classList[0] !== "h-checkbox" ? event.target.value : event.target.checked;
var newRowData: ICustomer = {...editRowData}
newRowData[fieldName as keyof ICustomer] = fieldValue;
setEditRowData(newRowData);
};
const handleEdit = (event: any, data: any) => {
event.preventDefault();
setEditSelectedId(data[0]);
Object.keys(editRowData).map((item: any, key: any) => {
editRowData[item as keyof ICustomer] = data[key+1]
})
};
const handleEditRowSubmit = (event: React.SyntheticEvent, isNew: boolean) => {
event.preventDefault();
const editedData: ICustomer = {};
Object.keys(editRowData).map((item: any, key: any) => {
if(key === 0){
editedData.id = editSelectedId;
}
editedData[item as keyof ICustomer] = editRowData[item as keyof ICustomer]
})
if(isNew) {
customers.shift();
editedData.id = customers.length ? (customers[customers.length-1].id)+1 : 1;
setCustomers([editedData, ...customers]);
toast.success("Add process successful");
}else{
let index = customers.findIndex(item => item.id === editSelectedId);
customers[index] = editedData;
toast.success("Update process successful");
}
setEditSelectedId(0);
};
const handleRemove = (id: string) => {
setCustomers(customers.filter(item => item.id !== id))
toast.success("Delete process successful");
}
const handleRemoveAll = () => {
setCustomers([]);
toast.success("Delete process successful");
}
const handleAddNew = () => {
Object.keys(editRowData).map((item: any) => {
editRowData[item as keyof ICustomer] = "";
})
setEditSelectedId(0);
if(!customers.length) {
setCustomers([{id:0,...editRowData}, ...customers]);
}else{
if(customers[0].id != 0) setCustomers([{id:0,...editRowData}, ...customers]);
}
}
const handleClose = (isNew: boolean) => {
setEditSelectedId(0);
if(isNew) {
setCustomers(customers.filter(item => item.id !== 0)) }
}
const handleOpenModal = (customers: ICustomer) =>{
openModal("edit-customer-modal", "Edit Customer Informations", customers);
}
const tableProps = {
theme:'dark',
language: "en",
addable:true,
editable:'inline',
removeAll:true,
searchable:true,
dataPerPage: 10,
editRowData,
editSelectedId,
handleAddNew,
handleEdit,
handleEditRowChange,
handleEditRowSubmit,
handleRemove,
handleRemoveAll,
handleOpenModal,
handleClose,
columns:[
{field: "last_name", title: "Last Name", sortable: true, align:"right"},
{field: "first_name", title:"First Name", sortable: true},
{field: "email_address", title:"Email Adress", sortable: true},
{field: "job_title", title:"Job Title", sortable: true},
{field: "is_active", title:"Is Active?", type: "checkbox", width: 80, align:"center"},
{field: "mobile_phone", title:"Mobile Phone", sortable: true},
{field: "profession_code", title:"Profession Code", type: "number", sortable: true, nullable: true},
{field: "birthday", title:"Birthday", type: "date", sortable: true, width: 100},
{field: "city", title:"City", sortable: true},
{field: "gross_salary", title:"Gross Salary", sortable: true, type: "select", data:["-2000$","2000-4000$","4000-6000$","6000$+"], width: 120},
{title: "", width:75} //command cell
],
fields:customers.map((item: ICustomer) => ([
item.id,
item.last_name,
item.first_name,
item.email_address,
item.job_title,
item.is_active,
item.mobile_phone,
item.profession_code,
item.birthday,
item.city,
item.gross_salary
]))
}
return (
<div>
<Table {...tableProps}/>
</div>
)
}
```
## API
|Prop |Description |Default |Optional |Type
|----------------|-------------------------------|-----------------------------|-----------------------------|-----------------------------|
|fields|data fields||false|array
|columns|field containing *'title''*, *'align'*, *'width'*, *'sortable'*, *'visibility'*, *'type'*, *'data'*(for select) ||false|array
|columns.field|column field||false|string
|columns.title|column title (if null the title will be like columns.field)||true|string
|columns.align|cell text align. *'left'*, *'right'* or *'center'*|left|true|string
|columns.width|cell width|150|true|number
|columns.sortable|column sort|false|true|bool
|columns.nullable|cell validator (if true it run validate for the cell)|false|true|bool
|columns.visibility|column visibility for only popup edit|false|true|bool
|columns.type|field type *'string'*, *'number'*, *'date'*, *'select'* or *'checkbox'*|'string'|true|string
|columns.data|select data (if the field type is 'select')||true|string array
|language|language *'en'*, *'tr'*, *'ru'*, *'de'*, *'cn'*, *'hi'*, *'es'*, *'fr'*, *'it'*, *'ar'*|'en'|true|string
|searchable|client side search (detailed search with column title. for example:'First Name:John')|false|true|bool
|editable|editable row prop *'inline'* or *'popup'*|false|true|string
|blurEdit|if another line is clicked at the time of editing, the editing is canceled|false|true|bool
|addable|addable prop (if true the add button will be visible)|false|true|bool
|removeAll|remove all (if true the remove all button will be visible)|false|true|bool
|dataPerPage|determines how much data is displayed per page|100|true|number
|mobileViewWidth|switches to mobile view when the screen pixel is smaller than the specified pixel|500|true|number
|loading|loading prop(dynamic)|false|true|bool
|theme|styled themes *'classic'*, *'dark'*, *'gray'*, *'purple'*, *'blue'*, *'red'*|'classic'|true|string
|editRowData|empty object state of data to be edited||true|object
|editSelectedId|string state of data to be edited||true|string
|handleAddNew|function to run when add new is clicked||true|function
|handleEdit|function to run when edit row is clicked||true|function
|handleEditRowChange|function to run when row cell changed||true|function
|handleEditRowSubmit|function to run when edit check is clicked||true|function
|handleClose|function to run when edit cancel is clicked||true|function
|handleRemove|function to run when remove row is clicked||true|function
|handleRemoveAll|function to run when remove all is clicked||true|function
|handleOpenModal|function to run when edit row is clicked (if editable prop is 'popup')||true|function
## NPM
[Superior React Table](https://www.npmjs.com/package/superior-react-table)
## Licence
MIT Licensed