so im using react-table library to display a tree grid table with mocked data but it isn't appearing like it should and it shows that there's one item on the table.
import React, { Component } from 'react';
import ReactTable from "react-table";
import 'react-table/react-table.css'
export default class TestTable extends Component {
state = {
data: [{
actionNo: "1",
action: "--",
productService: "Mobile Contract",
qty: 1,
startDate: Date.now(),
endDate: Date.now(),
account: 11111111,
mobileNo: 9111111,
amount: "--",
status: "Error"
}]
}
render() {
const { data } = this.state;
console.log(data);
const columns = [{
Header: 'Action No.',
accessor: 'actionNo'
}, {
Header: 'Action',
accessor: 'action',
}, {
acessor: 'productService',
Header: 'Product/Service',
}, {
acessor: 'qty',
Header: 'Qty.',
}, {
acessor: 'startDate',
Header: 'Start Date',
}, {
acessor: 'endDate',
Header: 'End Date',
}, {
acessor: 'account',
Header: 'Account',
}, {
acessor: 'mobileNo',
Header: 'Mobile No.',
}, {
acessor: 'amount',
Header: 'Amount.',
}, {
acessor: 'status',
Header: 'Status',
}]
return (
<ReactTable
data={data}
columns={columns}
pivotBy={["actionNo"]}
defaultPageSize={10}
showPagination={false}
resizable={false}
noDataText="No Data!"
className="-striped -highlight"
/>
);
}
}
This is the result of the snippet above
:
Soon i'll be using real data from a database but i need to test this out before messing around with micro service integration.
It's a typo. Please try using 'accessor' instead of 'acessor'.
Related
I already parsing API using axios. After that I got the value then I adding to properties Data in Datatable but still not working. The value not parse to Datatable. When I console.log the data is showing. I am use API from https://jsonplaceholder.typicode.com/users.
And hear is my code:
import "./css/jquery.dataTables.css";
import React, { Component } from "react";
import axios from "axios";
const $ = require("jquery");
$.Datatable = require("datatables.net");
export default class Tbl extends Component {
constructor(props) {
super(props);
this.state = {
users: [],
loading: true,
};
}
//option 1
async getUsersData() {
const res = await axios.get("https://jsonplaceholder.typicode.com/users");
console.log(res.data);
this.setState({ loading: false, users: res.data });
}
//option 2
async getUsersData1() {
const res = await axios.get("https://jsonplaceholder.typicode.com/users");
return res.data;
}
componentDidMount() {
//call option 1
this.getUsersData();
this.$el = $(this.el);
this.$el.DataTable({
data: this.state.users, //option 1
data: this.getUsersData1(), //option 2
columns: [
{ title: "Name", data: "name" },
{ title: "Username", data: "username" },
{ title: "Email", data: "email" },
{ title: "Phone", data: "phone" },
{ title: "Website", data: "website" }
],
});
}
componentWillMount() {}
render() {
return (
<table className="display" width="100%"
ref={(el) => (this.el = el)}>
</table>
);
}
}
I already try for option 1 and option 2 but still not working.
Thank,
The problem I can see here is that you initialize the plugin table in incorrect way. In order to include DataTable plugin, you should call as require('datatables.net')(window, $). Then after you have done loading data, you just simply call sync data to table again. Here is the snippet:
const $ = require("jquery");
require("datatables.net")(window, $);
// Keep as you have done
async getUsersData() {
const res = await axios.get("https://jsonplaceholder.typicode.com/users");
console.log(res.data);
this.setState({ loading: false, users: res.data });
}
// Init table data as component is mounted
componentDidMount() {
this.getUsersData().then(() => this.syncTable());
}
// Split as new function to init the datatable
syncTable() {
this.$el = $(this.el);
this.$el.DataTable({
data: this.state.users, //option 1
// data: this.getUsersData1(), //option 2
columns: [
{ title: "Name", data: "name" },
{ title: "Username", data: "username" },
{ title: "Email", data: "email" },
{ title: "Phone", data: "phone" },
{ title: "Website", data: "website" }
]
});
}
Here is the codesandbox for you: https://codesandbox.io/s/gallant-faraday-e25mk?file=/src/App.js
Use the "react-data-table-component" library. It is the best library for the data table.
Run this command to install it
npm install react-data-table-component styled-components
Then you have to import it in the react component page and use it
import DataTable from 'react-data-table-component';
const data = [{ id: 1, title: 'DataTable in ReactJS', year: '2021' } ...];
const columns = [
{
name: 'Name',
selector: 'name',
sortable: true,
},
{
name: 'Username',
selector: 'username',
sortable: true,
},
{
name: 'Email',
selector: 'email',
sortable: true,
},
{
name: 'Phone',
selector: 'phone',
sortable: true,
},
{
name: 'Website',
selector: 'website',
sortable: true,
},
];
class MyComponent extends Component {
render() {
return (
<datatable title="YourBlogCoach" columns="{columns}" data="{data}">
</datatable>
)
}
};
Check here for tutorial
I repeatedly getting this error with lot of attempts to fix that issue. Here I am giving my sample code.
index.js,
const app = (
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
ReactDOM.render(app, document.getElementById("root"));
App.js,
import React, { Component } from 'react';
import SlickGrid1 from "./containers/Grids/SlickGrid/GridExamples/Example1";
class App extends Component {
render () {
return (
<div>
<div id="myGrid"></div>
<SlickGrid1 />
</div>
);
}
}
export default App;
Example1.js,
import {Grid, Data} from 'slickgrid-es6';
import data from "../example-data";
const columns = [
{ id: "title", name: "Title", field: "title", maxWidth: 100, minWidth: 80 },
{ id: "duration", name: "Duration", field: "duration", resizable: false },
{ id: "%", name: "% Complete", field: "percentComplete" },
{ id: "start", name: "Start", field: "start" },
{ id: "finish", name: "Finish", field: "finish" },
{ id: "effort-driven", name: "Effort Driven", field: "effortDriven" }
];
const options = {
enableCellNavigation: true,
enableColumnReorder: true,
forceFitColumns: !true,
frozenColumn: 0,
frozenRow: 1
};
const dataView = new Data.DataView();
dataView.setItems([ ...data ]); // some data
export default new Grid("#myGrid", dataView, columns, options);
Even though, I defined the '#myGrid' div before the <SlickGrid1 /> component rendering, It always throws the same error. How do I fix this issue?
I think you are misunderstanding what exactly new Grid is creating in your code. You are trying to export it as a React component when in fact it is simply creating a grid based on a existing DOM element. Since you are calling new Grid in your export you are exporting an instance. It will try to create the Grid before your App component's render function is triggered, meaning that there is no valid target for it to bind to. Try exporting a factory function instead, like so:
Example1.js
import {Grid, Data} from 'slickgrid-es6';
import data from "../example-data";
const columns = [
{ id: "title", name: "Title", field: "title", maxWidth: 100, minWidth: 80 },
{ id: "duration", name: "Duration", field: "duration", resizable: false },
{ id: "%", name: "% Complete", field: "percentComplete" },
{ id: "start", name: "Start", field: "start" },
{ id: "finish", name: "Finish", field: "finish" },
{ id: "effort-driven", name: "Effort Driven", field: "effortDriven" }
];
const options = {
enableCellNavigation: true,
enableColumnReorder: true,
forceFitColumns: !true,
frozenColumn: 0,
frozenRow: 1
};
const dataView = new Data.DataView();
dataView.setItems([ ...data ]); // some data
export default () => new Grid("#myGrid", dataView, columns, options);
Then call this factory function in your componentDidMount hook of your App component:
App.js
import React, { Component } from 'react';
import SlickGrid1 from "./containers/Grids/SlickGrid/GridExamples/Example1";
class App extends Component {
componentDidMount() {
SlickGrid1();
}
render () {
return (
<div>
<div id="myGrid"></div>
</div>
);
}
}
export default App;
See this working example (I have omitted the test data).
I am trying to render some data in a react-table component however the data doesn't load. I have tested out with dummy data of the exact same format and it works fine. However when I make an API call and get data of the same format and push it to the list of data i'm passing to the react-table the table does not render it. Please help me identify the issue. Cheers
Setting up the columns:
columns: [
{
Header: "Employee ID",
accessor: "EmployeeID"
},
{
Header: "First Name",
accessor: "FirstName"
},
{
Header: "Last Name",
accessor: "LastName"
},
{
Header: "Date of Birth",
accessor: "DateOfBirth",
},
{
Header: "Status",
accessor: "Status",
},
{
Header: "Gender",
accessor: "Gender",
},
{
Header: "UpdatedDateUTC",
accessor: "UpdatedDateUTC",
}
]
What the data looks like:
{"EmployeeID":"63c571b3-bff0-4ce1-94f7-255c235580fa","FirstName":"Clive","LastName":"Thomas","Status":"ACTIVE","DateOfBirth":"/Date(697248000000+0000)/","Gender":"M","UpdatedDateUTC":"/Date(1533706298000+0000)/"}
My API call and how I'm saving the data item to state. (I console logged the value of the data I'm getting and it is in the correct format)
fetch('http://localhost:3100/employees')
.then((resp) => {
return resp.json()
})
.then((data) => {
let temp = this.state.posts;
temp.push(data.Employees[1])
this.setState({posts: temp})
console.log(this.state.posts)
})
.catch((error) => {
console.log(error, "catch the hoop")
})
The state and the 'posts' list storing the posts in state at bottom (with dummy data):
state = {
title: "Choose an Endpoint",
activeOrg: "Orginisation",
isExpanded: false,
activeLink: 0,
authLink:'',
response: '',
post: '',
responseToPost: '',
show: false,
modalContent:"",
token:'',
verifier:'',
org:'',
orginisations: [
{ id: 1, name: "ANU"},
{ id: 2, name: "Bar"},
{ id: 3, name: "FANG"},
{ id: 4, name: "Atlassian"}
],
list: [
{ id: 1, name: "Employees" },
{ id: 2, name: "Leave Applications" },
{ id: 3, name: "Pay Items" },
{ id: 4, name: "Payroll Calendars" },
{ id: 5, name: "Pay Runs" },
{ id: 6, name: "Pay Slips" },
{ id: 7, name: "Settings" },
{ id: 8, name: "Superfund Products" },
{ id: 9, name: "Timesheets" }
],
columns: [
{
Header: "Employee ID",
accessor: "EmployeeID"
},
{
Header: "First Name",
accessor: "FirstName"
},
{
Header: "Last Name",
accessor: "LastName"
},
{
Header: "Date of Birth",
accessor: "DateOfBirth",
},
{
Header: "Status",
accessor: "Status",
},
{
Header: "Gender",
accessor: "Gender",
},
{
Header: "UpdatedDateUTC",
accessor: "UpdatedDateUTC",
}
],
posts: [
{"EmployeeID":"63c571b3-bff0-4ce1-94f7-255c235580fa","FirstName":"Clive","LastName":"Thomas","Status":"ACTIVE","DateOfBirth":"/Date(697248000000+0000)/","Gender":"M","UpdatedDateUTC":"/Date(1533706298000+0000)/"}
]
}
Render function:
render() {
let myClass=""
let EndpointList = (
<div>
{this.state.list.map((i) => {
i.id === this.state.activeLink ? myClass="endpoint activeLink" : myClass="endpoint"
return <Endpoint
key={i.id}
name={i.name}
myClass={myClass}
clicked={(event) => this.handleClickEndpoint(i, i.id)}/>
})}
</div>
);
let orgContainer = ""
this.state.isExpanded ? orgContainer="orgItem expanded" : orgContainer="orgItem notExpanded"
let OrgList = (
<div className={orgContainer}>
{this.state.orginisations.map((o) => {
return <Orginisation
key={o.id}
name={o.name}
clicked={(event) => this.handleClickOrg(o,o.id)}
></Orginisation>
})}
</div>
);
var activeContent=<ReactTable columns={this.state.columns} data={this.state.posts} noDataText={"Loading..."}></ReactTable>
// const columns = Object.keys(this.state.data[0]).map((key, id)=>{
// console.log(key)
// return {
// Header: key,
// accessor: key,
// }
// })
return (
<Router>
<Route path='/' exact render={
() => {
return (
<div className='authenticateContainer'>
<a href={this.state.authLink} className='fill-div'>Click to Auntheticate</a>
</div>
)
}
}/>
<Route path='/home' render={
() => {
return (
<div>
<div className='sideBar'>
<div className='logoHolder'>
<img className='logo' alt='Logo' src={'./Assets/logo.png'}></img>
</div>
{EndpointList}
{OrgList}
<div style={{}} className="org button" onClick={this.expandOrg}>
<img className="orgLogo" alt='Logo' src={'./Assets/orgLogo.png'}></img>
{this.state.activeOrg}
</div>
</div>
<div className="container" id={this.state.title}>
{/* <button onClick={() => { this.setCredentials() }}>CLICK ME</button> */}
<div className="contentContainer">
<div className="head">
{this.state.title}
</div>
{activeContent}
</div>
</div>
</div>
)
}
} />
</Router>
);
}
}
Instantiating the react-table (also in render function above):
var activeContent=<ReactTable columns={this.state.columns} data={this.state.posts} noDataText={"Loading..."}></ReactTable>
I have also printed the dummy data that is successfully being inserted into the list as well as the API data which is not. As you can see they are clearly identical:
Not sure if this will resolve your issue, but IMO you should refactor this to be
fetch('http://localhost:3100/employees')
.then((resp) => {
return resp.json()
})
.then((data) => {
let temp = [...this.state.posts]
temp.push(data.Employees[1])
this.setState({
posts: temp,
data: data
})
console.log(this.state.posts) //this will not have the newest values yet, setState is async
})
.catch((error) => {
console.log(error, "catch the hoop")
})
It's not good practice to perform manipulations on react state
Why are you pushing Employees[1]? That would be the second record.
Currently I have created a component that wraps BootstrapTable. I have to define a constant that represents the columns of data. But, the way I have it right now seems to really clutter up my render method. I'd like to move it to its own file, but I'm not sure the best way to do this, because it requires callbacks that are defined in the class (notably the onUpdateClicked method).
If the way I have it is a fine way of doing things, that would be good to know. But, assuming I did want to move it to another file regardless, suggestions would be appreciated for my own edification. Thanks!
class MyTable extends Component {
onUpdateClicked() {
//do stuff
}
render() {
let {data} = {...this.props}
let columns = [
{
dataField: 'badge',
text: 'Badge',
sort: true
}, {
dataField: 'firstName',
text: 'First',
sort: true
}, {
dataField: 'lastName',
text: 'Last',
sort: true
}, {
dataField: 'email',
text: 'Email',
sort: true
}, {
dataField: 'loggedIn',
text: 'Logged In',
sort: true,
formatter: (cell, row) => {
if (row.loggedIn) {
return (<FontAwesomeIcon icon="check"/>)
}
}
}, {
dataField: 'update',
text: 'Update',
formatter: () => {
return (<Button onClick={this.onUpdateClicked} color="primary">Update</Button>)
}
},
];
return (
<div>
<BootstrapTable Bootstrap4 keyField='badge' data={data} columns={columns}/>
</div>
)
}
}
you can put the columns in a seperate file, but export a function that takes a function as a parameter to be used for the onClick
Columns.js
const columnsFn = someFunc => ([ // pass the function as a param.
{
dataField: 'badge',
text: 'Badge',
sort: true
}, {
dataField: 'firstName',
text: 'First',
sort: true
}, {
dataField: 'lastName',
text: 'Last',
sort: true
}, {
dataField: 'email',
text: 'Email',
sort: true
}, {
dataField: 'loggedIn',
text: 'Logged In',
sort: true,
formatter: (cell, row) => {
if (row.loggedIn) {
return (<FontAwesomeIcon icon="check"/>)
}
}
}, {
dataField: 'update',
text: 'Update',
formatter: () => {
return (<Button onClick={someFunc} color="primary">Update</Button>) // use it here
}
},
]);
export default columnsFn;
YourFile.js
import columnsFn from './columns';
class MyTable extends Component {
onUpdateClicked() {
//do stuff
}
render() {
const {data} = {...this.props}
const myColumns = columnsFn(this.onUpdateClicked); // pass the function here
return (
<div>
<BootstrapTable Bootstrap4 keyField='badge' data={data} columns={myColumns}/>
</div>
)
}
}
Here is React code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import ReactTable from 'react-table';
import _ from 'lodash';
import './style.css';
class GithubDataTable extends Component {
render() {
const { showData, savedData } = this.props;
let data = null;
if (showData === 'last') {
data = _.last(savedData);
} else {
data = savedData[showData];
}
console.log(data);
return (
<div>
{data && (
<ReactTable
data={data.items}
columns={[
{
Header: 'Data from GitHub',
columns: [
{
Header: 'Id',
id: 'id',
accessor: d => d.id,
},
{
Header: 'Repo Title',
id: 'repoTitle',
accessor: d => d.name,
},
{
Header: 'Owner',
id: 'owner',
accessor: d => d.owner.login,
},
{
Header: 'Link',
id: 'link',
accessor: d => d.html_url, // example data string "https://github.com/Michaelcj10/ReactJS-GitHub-User-Finder-App"
},
{
Header: 'Created at',
id: 'createdAt',
accessor: d => d.created_at.slice(0, 10),
},
{
Header: 'Updated at',
id: 'updatedAt',
accessor: d => d.updated_at.slice(0, 10),
},
{
Header: 'Stars',
id: 'stars',
accessor: d => d.stargazers_count,
},
{
Header: 'Forks',
id: 'forks',
accessor: d => d.forks_count,
},
],
},
]}
defaultPageSize={10}
pageSizeOptions={[5, 10, 15, 20]}
className="-striped -highlight"
/>
)}
</div>
);
}
}
function mapStateToProps(state) {
return {
savedData: state.savedData,
showData: state.showData,
};
}
export default connect(mapStateToProps, null)(GithubDataTable);
And I have problem with that particular element:
{
Header: 'Link',
id: 'link',
accessor: d => d.html_url, // https://github.com/Michaelcj10/ReactJS-GitHub-User-Finder-App
},
Data is shown as text, but how can I add html in that particular situation to this JSX to obtain a link
Not enought text hack:
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters...
Looks like you might be able to use the Cell property to display custom markup:
{
Header: 'Link',
id: 'link',
accessor: d => d.html_url, // https://github.com/Michaelcj10/ReactJS-GitHub-User-Finder-App
Cell: props => <a href={props.value}>{props.value}</a>
},