How to make each row of the table clickable in React? - javascript

There are quite a few answers that I found but none of them seem to work for my scenario.
I want to make each row clickable and log it on the console. How can I achieve this?
My React code is as follows:
class ConsumerList extends Component {
handleClick = building => {
console.log(building);
};
render() {
return (
<div className="table-responsive table-hover">
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Farm</th>
<th scope="col">Cost</th>
<th scope="col">Change</th>
</tr>
</thead>
<tbody>
{this.props.buildings.map(building => (
<tr key={building.id} onClick={() => this.handleClick(building)}>
<th scope="row">{building.id}</th>
<td>{building.name}</td>
<td>{building.farmName}</td>
<td>{building.cost}</td>
<td className="text-success">
<FontAwesomeIcon icon={faArrowDown} />
{building.change}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default ConsumerList;

onClick={(building) => this.handleClick(building)} modify this in your code while adding the listener. You will get the log into the console.

You need a routing setup.Use the withRouter high order component, and wrap that to the component that will push to history so that you get access to the history object, to perform various routing operations.
Check out the official documentation for more info
import React from "react";
import { withRouter } from "react-router-dom";
class ConsumerList extends React.Component {
handleClick = building => {
console.log(building);
this.props.history.push("/some/Path"); //path you want to redirect to
};
render() {
return (
<div className="table-responsive table-hover">
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Farm</th>
<th scope="col">Cost</th>
<th scope="col">Change</th>
</tr>
</thead>
<tbody>
{this.props.buildings.map(building => (
<tr key={building.id} onClick={(building) => this.handleClick(building)}>
<th scope="row">{building.id}</th>
<td>{building.name}</td>
<td>{building.farmName}</td>
<td>{building.cost}</td>
<td className="text-success">
<FontAwesomeIcon icon={faArrowDown} />
{building.change}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default withRouter(MyComponent);

Related

Text nodes cannot appear as a child of <tbody>

My code is really simple and I checked everything but this is getting this error repeatedly. Please suggest to me what can i change. I tried using but that dint work.I even checked other answers but they dint work.
import React from "react";
import { Button, Table } from "react-bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
import Employees from "./Employees";
const Home = () => {
return (
<>
<div>
<Table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{Employees && Employees > 0 ? Employees.map((item) => {
return (
<tr key={item.id}>
<td>{item.name}</td>
<td>{item.age}</td>
</tr>
);
})
: "No data available"}
</tbody>
</Table>
</div>
</>
);
};
export default Home;
If there is no data your table would look like
<table>
<tbody>
No data available
</tbody>
</table>
It needs to have a <tr> and a <td>

How to load data on button click using react

In my below code i have one table and when i select radio button and click on submit button then load the data and show in console. this is fine.
but in my table i have many data in table body. and when i select 1st row radio button then click submit button, then load data and show in console. that is fine. but again i select 2nd row radio button and click submit button, then i am not able to fetch data and show in console. and again i select the 3rd row and select radio button and click submit button then i m getting data in console.like that
why i'm getting like this?
class ProvFileRptSearchResult extends React.Component {
constructor(props) {
super();
this.state = {
pymtDetails:[],
data: [],
rowDetails:[],
checkbox: false
};
// this.handleFile=this.handleFile.bind(this);
this.handleClick=this.handleClick.bind(this);
}
handleClick() {
const apiUrl = "https://mocki.io/v1/b512f8b8-64ab-46e4-9e0c-9db538a0ad9e";
if (this.state.checkbox) {
fetch(apiUrl)
.then((response) => response.json())
.then((data) => {
this.setState({ data: data });
console.log("This is your data", data);
window.open("https://example.com", "_blank");
})
} else {
alert("Data not fetched!");
}
// console.log('click');
}
render()
{
return(
<div>
<div className="table-employee" style={{ marginTop:"20px",border:" 1.5px solid darkgray" }}>
<table className="table table-hover table-bordered table-sm">
<thead>
<tr >
<th scope="col">Select</th>
<th scope="col"> LOAD DATE</th>
<th scope="col"> FILE DATE</th>
<th scope="col"> SERVICE</th>
<th scope="col"> PROVISIONER CODE </th>
<th scope="col"> DESCRIPTION</th>
</tr>
</thead>
<tbody>
{
this.props.customerDetails.map((type,j)=>{
return(
<tr>
<td ><input type="radio" preventDefault name="select" key={j} onClick={(e) =>this.rowSelected(j)} value={this.state.checkbox}
onChange={(e) =>
this.setState({ checkbox: !this.state.checkbox })
}/></td>
<td> {type.provis_file_stamp}</td>
<td> {type.provis_file_hdrdt}</td>
<td> {type.service_code}</td>
<td>{type.provisioner_code}</td>
<td>{type.provisioner_desc}</td>
</tr>
)
})
}
</tbody>
</table>
</div>
<div className="btn-submit" >
<button className="btn btn-primary" style={{marginRight:"30px"}} type="submit" onClick={this.handleClick}>FILE</button>
</div>
</div>
)
}
what you are doing is, you are handling the data using single state variable.
take three separate variables for all your radio buttons
and handle them separately
you need some changes in checkbox value and input tags values and setstate,you can find the changes. below is the code that works:
import React from "react";
import ReactDOM from "react-dom";
class Test extends React.Component {
constructor(props) {
super();
this.state = {
data: [],
checkbox: 0
};
}
handleClick = () => {
const apiUrl = "https://mocki.io/v1/b512f8b8-64ab-46e4-9e0c-9db538a0ad9e";
if (this.state.checkbox) {
fetch(apiUrl)
.then((response) => response.json())
.then((data) => {
this.setState({ data: data });
console.log("This is your data", data);
window.open("https://example.com", "_blank");
});
} else {
alert("not load data!");
}
};
render() {
return (
<div>
<div
className="table-employee"
style={{ marginTop: "20px", border: " 1.5px solid darkgray" }}
>
<table className="table table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col">Select</th>
<th scope="col"> LOAD DATE</th>
<th scope="col"> FILE DATE</th>
<th scope="col"> SERVICE</th>
<th scope="col"> PROVISIONER CODE </th>
<th scope="col"> DESCRIPTION</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input
value={this.state.checbox === 1 ? true : false}
onChange={(e) => this.setState({ checkbox: 1 })}
type="radio"
preventDefault
name="select"
/>
</td>
<td>dfgrty</td>
<td>fgfg</td>
<td>fgfg</td>
<td>erer</td>
<td>uuio</td>
</tr>
<tr>
<td>
<input
value={this.state.checbox === 2 ? true : false}
onChange={(e) => this.setState({ checkbox: 2 })}
type="radio"
preventDefault
name="select"
/>
</td>
<td>dfgrty</td>
<td>fgfg</td>
<td>fgfg</td>
<td>erer</td>
<td>uuio</td>
</tr>
<tr>
<td>
<input
value={this.state.checbox === 1 ? true : false}
onChange={(e) => this.setState({ checkbox: 3 })}
type="radio"
preventDefault
name="select"
/>
</td>
<td>dfgrty</td>
<td>fgfg</td>
<td>fgfg</td>
<td>erer</td>
<td>uuio</td>
</tr>
</tbody>
</table>
</div>
<div className="btn-submit">
<button
className="btn btn-primary"
style={{ marginRight: "30px" }}
type="submit"
onClick={this.handleClick}
>
submit
</button>
</div>
</div>
);
}
}
ReactDOM.render(<Test />, document.getElementById("root"));
// https://mocki.io/v1/b512f8b8-64ab-46e4-9e0c-9db538a0ad9e
// http://codeskulptor-assets.commondatastorage.googleapis.com/assets_clock_minute_arrow.png

Iterating over a series of objects and inserting then into a Bootstrap table

All in all trying to loop over a jsonplaceholder's (/users) name, username, and email. Im getting the data with the help of axios and im displaying it through react. I have two seperate files: App.js (the one that comes with react) and AlbumList.js
In App.js:
import React, { Component } from 'react'
import './App.css';
import AlbumList from './Components/AlbumList';
class App extends Component {
render() {
return (
<div className="App">
<AlbumList/>
</div>
)
}
}
export default App
And in Album.List
import axios from 'axios';
import React from 'react';
export default class AlbumList extends React.Component {
state = {
persons: [],
};
componentDidMount() {
axios.get('https://jsonplaceholder.typicode.com/users').then(res => {
console.log(res);
this.setState({ persons: res.data });
});
}
render() {
return (
<div>
<table class="table">
<caption>List of users</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">name</th>
<th scope="col">username</th>
<th scope="col">e-mail</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row"></th>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
</tbody>
</table>
{/* { this.state.persons.map(person => <div>{person.name} | {person.username} | {person.email}</div> )} */}
</div>
)
}
}
The table im using is the one that bootstrap offers, the default one. How do I do this? thanks
You need to map the data you got from your fetch request to the "tbody" tag, here you are just mapping the result in a div.
Check below your code with the modification needed:
render() {
return (
<div>
<table class="table">
<caption>List of users</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">name</th>
<th scope="col">username</th>
<th scope="col">e-mail</th>
</tr>
</thead>
<tbody>
{ this.state.persons.map(person =>
<tr>
<th scope="row"></th>
<td>{person.name}</td>
<td>{person.username}</td>
<td>{person.email}</td>
</tr> )}
</tbody>
</table>
</div>
)
}
Edit: typo

React don't render a map function of an Axios call

I'm trying to make a shopping cart table in which it shows an image, name of the product and a remove button. I've the id of each product from the localStorage and call all the data of that id with Axios.get(by id).
I'd created a table to show the price, image and name of the product, but my .map function don't show the info in the website (even though I can see it with a console.log). Here is the code:
import Axios from "axios";
import React from "react";
function ClientCardBlock() {
let memory = window.JSON.parse(localStorage.getItem("toy"));
console.log(memory); **this log shows me that all the IDs are now in an array**
const renderItems = () => {
memory.map(
async (toy_id) =>
await Axios.get(`http://************/${toy_id}`).then(
(response) => {
const toy = response.data;
console.log(toy.price); **this log show me the price of each toy, so it's working**
return (
<tr key={toy._id}>
<th>
<img
alt=""
className="card-img-top embed-responsive-item"
src={`http://*********/${toy.images}`}
/>
</th>
<th>$ {toy.price}</th>
<th>
<button>Remove</button>
</th>
</tr>
);
}
)
);
};
return (
<div>
<table className="table table-bordered">
<thead>
<tr>
<th scope="col">Image product</th>
<th scope="col">Product</th>
<th scope="col">Remove</th>
</tr>
</thead>
<thead>{renderItems()}</thead>
</table>
</div>
);
}
export default ClientCardBlock;
Normally you'd be able to just change it so that renderItems is a functional component.
function RenderItems() {
return memory.map...(etc)
}
...
<thead><RenderItems /></thead>
but since this is an async function, you need to use a useEffect. This useEffect gets the data and saves it into your component state. Then once it exists, it will render later. The key point is to seperate the fetching from the rendering.
function ClientCardBlock() {
const [data, setData] = useState([]);
useEffect(() => {
/* this runs on component mount */
const memory = window.JSON.parse(localStorage.getItem("toy"));
Promise.all(memory.map((toy_id) => Axios
.get(`http://************/${toy_id}`)
.then((response) => response.data)))
/* Wait on the Promise.All */
.then(newData => {
/* Set the data locally */
setData(newData);
});
}, []);
return (
<div>
<table className="table table-bordered">
<thead>
<tr>
<th scope="col">Image product</th>
<th scope="col">Product</th>
<th scope="col">Remove</th>
</tr>
</thead>
<thead>
{data.map(toy => (
<tr key={toy._id}>
<th>
<img
alt=""
className="card-img-top embed-responsive-item"
src={`http://*********/${toy.images}`}
/>
</th>
<th>$ {toy.price}</th>
<th>
<button>Remove</button>
</th>
</tr>
)}
</thead>
</table>
</div>
);
}
export default ClientCardBlock;

React display props on table from props.object

I have a component in react where I pass so data in a prop:
<Mycomponent names={[{name: 'peter'},{name: 'pan'}]} />
Then I have a component which has a table and where I want to display the data in a
Here is the component
import React from 'react';
const Mycomponent = (props) => <div>
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>{ props.names }</td>
</tr>
</tbody>
</table>
</div>;
export default Mycomponent;
How do I loop and display each name in a <tr><td>{props.names.name}</td></tr> ?
<tbody>
{
props.names.map( ({name}, i) => <tr key={i}><td>{ name }</td></tr> )
}
</tbody>
will iterate over all of props.names and return a tr for each

Categories

Resources