I'm using API Values primaryKey to change data represented on Click, but the function doesnt seem to work. and No Errors are thrown. I'm unable to find whats going wrong here.
What I'm trying to do here is - By default the table outputs multiple stocks with multiple columns for each , when clicked on button
it should use the key value of that stock to represent only that single stock with its columns.
Here is my part of the code:
handleClick = (props) => {
return (
<div>
{this.state.data.filter(data => data.includes({props})).map(filteredData => (
<li>
{filteredData}
</li>
))};
</div>
);
}
renderArray = () => {
return (
<table className="table">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Price/ Chng</th>
<th>Mkt Cap</th>
<th>Volume</th>
<th>Turnover</th>
</tr>
</thead>
<tbody>
{this.state.data.map(item => {
return (
<tr key={item.co_S}>
<button onCLick={this.setState = () => this.handleClick(item.co_S)}><td >{item.co_N}</td></button>
<td>{item.price}</td>
<td>{item.p_chng_pc}</td>
<td>{item.Mkt_cap}</td>
<td>{item.volume}</td>
<td>{item.volume * item.price}</td>
</tr>
);
})};
</tbody>
</table>
);
}
render() {
return (
<this.renderArray />
)
}
}
export default StocksHomePage2;
class App extends React.Component {
state = {
data: [
{
co_S: 1,
co_N: 1,
price: 100,
volume: 20,
},
{
co_N: 2,
co_S: 2,
price: 30,
volume: 7,
},
],
};
handleClick = (props) => {
this.setState({
data: this.state.data.filter((item) => item.co_S === props),
});
};
renderArray = () => {
return (
<table className="table">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Price/ Chng</th>
<th>Mkt Cap</th>
<th>Volume</th>
<th>Turnover</th>
</tr>
</thead>
<tbody>
{this.state.data.map((item) => {
return (
<tr key={item.co_S}>
<button onClick={() => this.handleClick(item.co_S)}>
<td>{item.co_N}</td>
</button>
<td>{item.price}</td>
<td>{item.p_chng_pc}</td>
<td>{item.Mkt_cap}</td>
<td>{item.volume}</td>
<td>{item.volume * item.price}</td>
</tr>
);
})}
</tbody>
</table>
);
};
render() {
return this.renderArray();
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Related
The code that I posted below is the API request from which I make a table. This table has 4 columns: id, userid, title. I want to understand how I can sort by userid and title, as shown in the photo. It would be great if the steps were described in detail.
I'm trying to group the tab as shown in the photo, but I can't.
Can you suggest/show me how to do this?
Also wanted to know how to reset the group value of a column?
I will be grateful for any help.
My code:
import React from "react";
import "./GroupByUserID.css";
import { Link } from "react-router-dom";
export default class GroupByUserID extends React.Component {
// Constructor
constructor(props) {
super(props);
this.state = {
items: [],
};
}
componentDidMount = () => {
this.apiFetch();
};
//Fetch data from API
apiFetch = () => {
return fetch("https://jsonplaceholder.typicode.com/todos")
.then((res) => res.json())
.then((json) => {
this.setState((prevState) => {
return { ...prevState, items: json };
});
});
};
// Sort UserID
setSortedItemsUserID = () => {
const { items } = this.state;
const sortedUserID = items.sort((a, b) => {
if (a.userId < b.userId) {
return items.direction === "ascending" ? -1 : 1;
}
if (a.userId > b.userId) {
return items.direction === "ascending" ? 1 : -1;
}
return 0;
});
console.log(sortedUserID);
this.setState((prevState) => {
return { ...prevState, items: sortedUserID };
});
};
render() {
const { items } = this.state;
return (
<div>
<h1>Home Page</h1>
<table>
<thead>
<tr>
<th>
<Link target="self" to="/">
View Normal
</Link>
</th>
<th>Group By UserID</th>
</tr>
</thead>
<thead>
<tr>
<th>
User ID
<button
type="button"
onClick={() => this.setSortedItemsUserID()}
>
⬇️
</button>
</th>
<th>Title</th>
</tr>
</thead>
<tbody>
{items.map((item) => (
<tr key={item.userId + item.title}>
<td>{item.userId}</td>
<td>{item.title}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
So I've created this Table component, intended to be reusable.
But I have this problem where the data didn't fill all the row correctly. It stacked up on first two rows.
Here's my code so far:
Menu.js
export const AddMenu = () => {
const theadData = ["No", "Name", "Category", "Price"];
const tbodyData = [
{
id: 1,
items: [1, "Hamburger", "Fast Food", 150],
},
{
id: 2,
items: [2, "Pizza", "Fast Food", 100],
},
];
return (
<div className="container">
<h1>Add Menu</h1>
<Table theadData={theadData} tbodyData={tbodyData} />
</div>
);
};
Table.js
export const Table = ({
theadData,
tbodyData,
}) => {
return (
<div className="table">
<table>
<thead>
<tr>
{theadData.map((item) => {
return <th title={item}>{item}</th>;
})}
</tr>
</thead>
<tr>
{tbodyData.map((item) => {
return <td key={item}>{item.items}</td>;
})}
</tr>
</tbody>
</table>
</div>
);
};
Thanks btw, hope to get an answer.
Add second map to loop over rows, and then loop over cells, like this:
{
tbodyData.map((row, index) => (
<tr key={index}>
{row.map((item) => {
return <td key={item}>{item}</td>;
})}
</tr>
));
}
i am trying to sort html table by ASC and desc order but this table is not working properly its working only for first column when i put id name can you please help me for make this work sorting func by ASC and Desc. this is my code so far i tried but its not working Thanks
import React from "react";
class Th extends React.Component {
handleClick = () => {
const { onClick, id } = this.props;
onClick(id);
};
render() {
const { value } = this.props;
return <th onClick={this.handleClick}>{value}</th>;
}
}
class App extends React.Component {
state = {
users: []
};
async componentDidMount() {
const res = await fetch(
`https://run.mocky.io/v3/6982a190-6166-402e-905f-139aef40e6ef`
);
const users = await res.json();
this.setState({
users
});
}
handleSort = id => {
this.setState(prev => {
return {
[id]: !prev[id],
users: prev.users.sort((a, b) =>
prev[id] ? a[id] < b[id] : a[id] > b[id]
)
};
});
};
render() {
const { users } = this.state;
return (
<table>
<thead>
<tr>
<Th onClick={this.handleSort} id="mileage" value="Mileage" />
<Th onClick={this.handleSort} id="overall_score" value="Overall score" />
<Th onClick={this.handleSort} id="fuel_consumed" value="Fuel Consumed" />
</tr>
</thead>
<tbody>
{users.map(user => (
<tr>
<td>{user.span.mileage.value}</td>
<td>{user.span.overall_score.value}</td>
<td>{user.span.fuel_consumed.value}</td>
</tr>
))}
</tbody>
</table>
);
}
}
export default App;
To make it works you need to change a few thigs:
the setState merges new data with old one, so [id]: !prev[id] adds new property to state for each column you filter without removing old one. It's better to store column to filter in dedicated state property (e.g. sortBy).
fix sorting function to make it sorting the users by correct object properties
remove async from componentDidMount and change fetch to use then/catch instead of async/await (it makes your code more React-ish).
Use example below as an inspiration:
class App extends React.Component {
state = {
sortBy: null,
order: "ASC",
users: []
};
componentDidMount() {
fetch(`https://run.mocky.io/v3/6982a190-6166-402e-905f-139aef40e6ef`)
.then(response => response.json())
.then(users => this.setState({users}))
.catch(err => console.log('Error', err));
}
handleSort = id => {
this.setState(prev => {
const ordered = prev.users.sort((a, b) =>
prev.order === "ASC"
? a["span"][id]["value"] < b["span"][id]["value"]
: a["span"][id]["value"] > b["span"][id]["value"]
);
return {
sortBy: id,
order: prev.order === "ASC" ? "DESC" : "ASC",
users: ordered
};
});
};
render() {
const { users } = this.state;
return (
<table>
<thead>
<tr>
<Th onClick={this.handleSort} id="mileage" value="Mileage" />
<Th
onClick={this.handleSort}
id="overall_score"
value="Overall score"
/>
<Th
onClick={this.handleSort}
id="fuel_consumed"
value="Fuel Consumed"
/>
</tr>
</thead>
<tbody>
{users.map(user => (
<tr>
<td>{user.span.mileage.value}</td>
<td>{user.span.overall_score.value}</td>
<td>{user.span.fuel_consumed.value}</td>
</tr>
))}
</tbody>
</table>
);
}
}
class Th extends React.Component {
handleClick = () => {
const { onClick, id } = this.props;
onClick(id);
};
render() {
const { value } = this.props;
return <th onClick={this.handleClick}>{value}</th>;
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Keep in mind that in only works with the current data schema and fields you already have. If you want to change the fields to sort by you need to update sorting function.
I'm trying to create a CRUD application in react, and I have encountered several problems.
How can I remove an item from the table?
Is it possible to pass id to Info component in render method? How can I later link it to the element?
Why does the e.PreventDefault () method cause an error when I try to delete?
import React, { Component } from 'react';
const Info = ({ index, login, pass }) => (
<>
<thead>
<tr>
<th>ID</th>
<th>LOGIN</th>
<th>PASSWORD</th>
</tr>
</thead>
<tbody>
<tr>
<td key={index}>{index}{alert(index)}</td>
<td>{login}</td>
<td>{pass}</td>
</tr>
</tbody>
<input type="submit" value='X' onClick={() => this.del(index)}></input>
</>
);
class List extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
login: "",
pass: "",
};
this.add = this.add.bind(this);
this.show = this.show.bind(this);
this.del = this.show.bind(this);
}
add(e) {
e.preventDefault();
this.setState({
[e.target.name]: e.target.value,
});
}
show(e) {
e.preventDefault();
if (!this.state.login.length || !this.state.pass.length) {
return;
}
else {
const newUser = {
login: this.state.login,
pass: this.state.pass,
};
this.setState(state => ({
data: state.data.concat(newUser),
}))
}
}
del(index) {
const tab = this.state.data.filter((temp) => temp.index !== index);
this.setState(({
data: tab
}));
}
render() {
return (
<div>
<form onSubmit={this.show}>
<label>Login</label><br></br><input type='text' name='login' onChange={e => this.add(e)}></input><br></br>
<label>Password</label><br></br><input type='text' name='pass' onChange={e => this.add(e)}></input><br></br>
<input type="submit" value="Add"></input>
</form>
<table>
{this.state.data.map((val, index) => (
<>
<thead>
<tr>
<th>ID</th>
<th>LOGIN</th>
<th>PASSWORD</th>
</tr>
</thead>
<tbody>
<tr>
<td key={index}>{index}</td>
<td>{val.login}</td>
<td>{val.pass}</td>
</tr>
</tbody>
<input type="submit" value='X' onClick={() => this.del(index)}></input>
</>
))}
</table>
</div>
)
}
}
export default List;
There are small corrections in your code.
this.del = this.show.bind(this); should be this.del = this.del.bind(this);
You are trying to remove the element from the state data using index (this.state.data.filter((temp) => temp.index !== index);) but the element inside the data doesn't have an index property.
In that case, you can use splice to delete the element from the data.
class List extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
login: "",
pass: "",
};
this.add = this.add.bind(this);
this.show = this.show.bind(this);
this.del = this.del.bind(this);
}
add(e) {
e.preventDefault();
this.setState({
[e.target.name]: e.target.value,
});
}
show(e) {
e.preventDefault();
if (!this.state.login.length || !this.state.pass.length) {
return;
}
else {
const newUser = {
login: this.state.login,
pass: this.state.pass,
};
this.setState(state => ({
data: state.data.concat(newUser),
}))
}
}
del(index) {
let {data}=this.state
data.splice(index, 1);
this.setState(({
data
}));
}
render() {
return (
<div>
<form onSubmit={this.show}>
<label>Login</label><br></br><input type='text' name='login' onChange={e => this.add(e)}></input><br></br>
<label>Password</label><br></br><input type='text' name='pass' onChange={e => this.add(e)}></input><br></br>
<input type="submit" value="Add"></input>
</form>
<table>
{this.state.data.map((val, index) => (
<React.Fragment>
<thead>
<tr>
<th>ID</th>
<th>LOGIN</th>
<th>PASSWORD</th>
</tr>
</thead>
<tbody>
<tr>
<td key={index}>{index}</td>
<td>{val.login}</td>
<td>{val.pass}</td>
</tr>
</tbody>
<input type="submit" value='X' onClick={() => this.del(index)}></input>
</React.Fragment>
))}
</table>
</div>
)
}
}
ReactDOM.render(<List />, document.querySelector("#app"))
Here is the demo jsFiddle
Hope it helps :)
The problem is I don't know how to put effect from parent component to child component...
I'm creating sorting function.
tableSort = (event, sortKey) => {
const {data} = this.state;
data.sort((a,b) => a[sortKey].localeCompare(b[sortKey]) )
this.setState({ data })
}
and then I'm trying to render that in my table
render() {
const {data} = this.state
return (
<>
<Table>
<Thead>
<Tr>
<Th onClick={e => this.tableSort(e, 'pool number')}>Pool Number</Th>
<Th>Sender</Th>
<Th>Not Routed Reason</Th>
<Th>Sent Date Time</Th>
<Th>Requested Delivery Report Mask Text</Th>
<Th>Delivery Report Received Date Time</Th>
<Th>isUnicode</Th>
<Th>MessageUUID</Th>
</Tr>
</Thead>
{this.renderData(data)}
</Table>
</>
)
}
The child component is called in this component and it locks like this..
import React from 'react'
import { Tbody, Tr, Td } from 'react-super-responsive-table'
const TablePageList = ({data}) => {
const {poolNumber, sender, notRoutedReason, sentDateTime, requestedDeliveryReportMaskText,
deliveryReportReceivedDateTime, isUnicode, messageUUID} = data
return (
<Tbody>
<Tr>
<Td>{poolNumber}</Td>
<Td>{sender}</Td>
<Td>{notRoutedReason}</Td>
<Td>{sentDateTime}</Td>
<Td>{requestedDeliveryReportMaskText}</Td>
<Td>{deliveryReportReceivedDateTime}</Td>
<Td>{isUnicode}</Td>
<Td>{messageUUID}</Td>
</Tr>
</Tbody>
)
}
export default TablePageList
So how can I access and sort my Td from Th?
You should call the child component from parent. You didn't call any child component.
Try below code.
import child compenent url.
import TablePageList from "./TablePageList";
And then keep state data.
this.state = {
data:[]
}
Also change function setState and order data.
tableSort = (event, sortKey) => {
const {data} = this.state;
data.sort((a,b) => a[sortKey].localeCompare(b[sortKey]) )
this.setState({ data: data })
}
And call TablePageList component below </Thead>
render() {
const { data } = this.state;
return (
<Table>
<Thead>
<Tr>
<Th onClick={e => this.tableSort(e, "pool number")}>
Pool Number
</Th>
<Th>Sender</Th>
<Th>Not Routed Reason</Th>
<Th>Sent Date Time</Th>
<Th>Requested Delivery Report Mask Text</Th>
<Th>Delivery Report Received Date Time</Th>
<Th>isUnicode</Th>
<Th>MessageUUID</Th>
</Tr>
</Thead>
{data.map(element => {
<TablePageList data={element}></TablePageList>;
})}
</Table>
);
}
And then you get data and fill it.
const TablePageList = ({ data }) => {
return (
<Tbody>
<Tr>
<Td>{data.poolNumber}</Td>
<Td>{data.sender}</Td>
<Td>{data.notRoutedReason}</Td>
<Td>{data.sentDateTime}</Td>
<Td>{data.requestedDeliveryReportMaskText}</Td>
<Td>{data.deliveryReportReceivedDateTime}</Td>
<Td>{data.isUnicode}</Td>
<Td>{data.messageUUID}</Td>
</Tr>
</Tbody>
);
};