Superior React Table
A multilanguage, editable, addable, removable, sortable, detailed searchable, responsive table component for react.
Installation
npm install superior-react-table
Live Demo
https://halidunal.github.io > Portfolio > Superior React Table
Example Code
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
Licence
MIT Licensed