How make table row clickable? - reactjs

import React from 'react'
import './myform.css'
const Emp=()=>{
const players=[
{
id: 1,
fullName: 'Employee 1',
email:'example1#mail.com',
joiningdate: '05/08/2020',
},
{
id: 2,
fullName: 'Employee 2',
email:'example2#mail.com',
},
{
id: 3,
fullName: 'Employee 3',
email:'example3#mail.com',
joiningdate: '10/08/2020'
},
{
id: 4,
fullName: 'Employee 4',
email:'example4#mail.com',
joiningdate: '05/08/2020'
},
]
/* I want to make row clickable and when it clicked information
from whole row is display on other page
I trying so much to make row clickable but it fails,
I got error "rowSelect() is undefined!!!" */
rowSelect=(event)=>{
console.log(event);
}
const renderPlayer=(player, index)=>{
return(
<tr key={index} onClick={this.rowSelect}>
<td>{player.id}</td>
<td>{player.fullName}</td>
<td>{player.email}</td>
<td>{player.joiningdate}</td>
</tr>
)
}
> //return data into table format on UI
return(
<div className='emp'>
<table className='border'>
<thead>
<tr >
<th>Id</th>
<th>Full Name</th>
<th>Email</th>
<th>Joining Date</th>
</tr>
</thead>
<tbody>
{players.map(renderPlayer)}
</tbody>
</table>
</div>
)
}
export default Emp

Since this is a functional component you need to declare your function as
function rowSelect(event) {
}
or
const rowSelect = event => {
}
then call it in your onClick like this
<tr key={index} onClick={rowSelect}>

Related

How to convert array to json and bind the json data in a table in react js

I have an array of,
I am trying to convert that to a JSON , so I can bind the data in a bootstrap table like this,
import "bootstrap/dist/css/bootstrap.min.css";
import Table from "react-bootstrap/Table";
function Home() {
const customers = [
{
CustomerId: 1,
Name: "John Hammond",
Country: "United States",
},
{
CustomerId: 2,
Name: "Mudassar Khan",
Country: "India",
},
{
CustomerId: 3,
Name: "Suzanne Mathews",
Country: "France",
},
{
CustomerId: 4,
Name: "Robert Schidner",
Country: "Russia",
},
];
return (
<div className="container">
<div className="row">
<div className="col-12">
<Table striped bordered hover size="sm">
<thead>
<tr>
<th>File Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
{customers.map(customers=>
<tr>
<td>{customers.Name}</td>
<td>{customers.Country}</td>
</tr>
)}
</tbody>
</Table>
</div>
</div>
</div>
);
}
export default Home;
Like in this example, they are binding Name and country from customers, I want to bind path data and mode data from the array and bind to the table.
I tried JSON.stringify but it is not working. How to do this?
This is the full code
import "bootstrap/dist/css/bootstrap.min.css";
import Table from "react-bootstrap/Table";
import { Octokit } from "octokit";
function Home() {
getContents();
let jsonString = '';
const customers = [
{
CustomerId: 1,
Name: "John Hammond",
Country: "United States",
},
{
CustomerId: 2,
Name: "Mudassar Khan",
Country: "India",
},
{
CustomerId: 3,
Name: "Suzanne Mathews",
Country: "France",
},
{
CustomerId: 4,
Name: "Robert Schidner",
Country: "Russia",
},
];
let contentResponse = "";
let valueArray = [];
async function getContents() {
try {
return await new Promise(async (resolve, reject) => {
try {
const octokit = new Octokit({
auth: "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",
});
const response = await octokit.request(
"GET /repos/KaranS0406/React/git/trees/4c1289a6405a5d87de6f1071ce723ee8b94be276?recursive=1"
);
console.log(response.data.tree);
contentResponse = response.data.tree;
Object.entries(contentResponse).forEach((element) => {
const [key, value] = element;
valueArray.push(value);
});
resolve("success");
} catch (error) {
reject("error");
}
});
} catch (error) {
console.log(error);
}
}
return (
<div className="container">
<div className="row">
<div className="col-12">
<Table striped bordered hover size="sm">
<thead>
<tr>
<th>File Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
{customers.map(customers=>
<tr>
<td>{customers.Name}</td>
<td>{customers.Country}</td>
</tr>
)}
</tbody>
</Table>
</div>
</div>
</div>
);
}
export default Home;
Add this after contentResponse line and check with console.log if is that what do you want.?
const convertdata = contentResponse.map((item) =>{
let obj={
Name:item.path,
Country:item.mode
}
})
Judging by what you get in the console, you already have what you need, just replace customers with your array (response.data.tree) and replace also name and country with path and mode.
{myArray.map(element =>
<tr>
<td>{element.path}</td>
<td>{element.mode}</td>
</tr>
)}

Regular react table to MaterialTable

How can I add data in my Material Table from an array?
I have the following table:
<table className="table">
<thead>
<tr>
<th>Text1</th>
<th>Text2</th>
<th>text3 Comb</th>
</tr>
</thead>
<tbody>
{arr.map((values, index) => {
const textComb = `${values.text1}, ${values.text2}`;
return (
<tr key={index}>
<td>{values.text1}</td>
<td>{values.text2}</td>
<td>{textComb}</td>
<td></td>
</tr>
)
})}
</tbody>
</table>
I have too many data, so I'm trying to use MaterialTable to have a search, sort, and pagination option.
<MaterialTable
columns={[
{title: 'Text1', field: 'text1'},
{title: 'Text2', field: 'text2'},
{title: 'Text3', field: 'text3'}
]}
data={
arr((values, index) => {
{
// I'm confused here
}
})
}
/>
try this-
const createData = item => ({
text1: item.text1,
text2: item.text2,
text3: `${item.text1}, ${item.text2}`
});
const data = arr.map(item => createData(item));
check demo here - https://codesandbox.io/s/material-table-example-5cohx?file=/src/App.js

How to delete item seleted in table product

I am trying to delete a product, but it's doesn't show success. I do not know how to get the id of that product to delete
My button onClick = {handleDelete} is import from component in other folder. I try to create handleDelete function, but I missing something in this case.
This is my code for that section
import React, { useState, useEffect } from "react";
import { Container, Row, Col, Table } from "react-bootstrap";
import Loading from "../../components/Loading";
import Button from "../../components/Button/index"
import firebaseApp from "../../api/config";
const ProductTableList = ({
products,
loading,
fetchProductRequest
}) => {
useEffect(() => {
fetchProductRequest();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const firebaseDb = firebaseApp.database();
const [currentId, setCurrentId] = useState("");
if (loading) {
return (
<Container>
<Row>
<Col>
<Loading />
</Col>
</Row>
</Container>
);
}
const handleDelete = (id) => {
const productId = firebaseDb.ref().push().key;
if (window.confirm("Are you sure to delete this record?")) {
firebaseDb
.ref("products")
.child(`products/${productId}`)
.remove((err) => {
if (err) console.log(err);
else setCurrentId("");
});
}
}
const handleUpdate = (event) => {
//TODO
}
return (
<Table striped bordered hover className="product-table">
<thead>
<tr>
<th>No.</th>
<th className="image">Image</th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{!!products && products.length > 0 ? (
products.map((product, index) => {
return (
<tr key={index}>
<td>{index}</td>
<td>{product.image}</td>
<td>{product.name}</td>
<td>{product.category}</td>
<td>{product.price}</td>
<td>{product.description}</td>
<td>
<Button onClick={handleDelete} btnText="Delete" />
<Button onClick={handleUpdate} btnText="Update" />
</td>
</tr>
);
})
) :
(
<tr><td className="center-title">Product list is empty!</td></tr>
)}
</tbody>
</Table>
)
}
export default ProductTableList;
Can anyone help me? How do I delete the product that I have selected
Can anyone explain or support for me why? Thank you so much
I made a example, you need to add your function on button click and use your item id to be removed.
import React, { useState, useEffect } from "react";
import { Table } from "react-bootstrap";
const ProductTableList = () => {
const [currentId, setCurrentId] = useState("");
const [products, setProducts] = useState([{
image: 'image',
name: '01',
category: '01',
price: '01',
description: '01'
},
{
image: 'image',
name: '02',
category: '02',
price: '02',
description: '02'
},
{
image: 'image',
name: '03',
category: '03',
price: '03',
description: '03'
}])
const handleDelete = (id) => {
const removeItem = products.filter((item) => item !== products[id])
setProducts(removeItem)
}
return (
<Table striped bordered hover className="product-table">
<thead>
<tr>
<th>No.</th>
<th className="image">Image</th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{!!products && products.length > 0 ? (
products.map((product, index) => {
return (
<tr key={index}>
<td>{index}</td>
<td>{product.image}</td>
<td>{product.name}</td>
<td>{product.category}</td>
<td>{product.price}</td>
<td>{product.description}</td>
<td>
<button onClick={() => handleDelete(index)}>Delete</button>
</td>
</tr>
);
})
) :
(
<tr><td className="center-title">Product list is empty!</td></tr>
)}
</tbody>
</Table>
)
}
export default ProductTableList;
Also, avoid index as element key
{ items.map((item, index) => (<li key={index}>{item}</li>)) }
When a list item was added or removed, and the key kept the same, the React assumed that the DOM element had not changed, and the app could not render.
An alternative to cases that the list doesn't have a unique ID is to generate one using shortID.
https://www.npmjs.com/package/shortid

No rows rendered, no errors detected

In my React component, trying to generate rows from the state. State object is being populated, but no rows is being rendered:
class DataTable extends React.Component {
constructor(props) {
super(props);
this.renderTableData = this.renderTableData.bind(this);
this.fetchData = this.fetchData.bind(this);
this.state = {
Houses: []
};
}
componentDidMount() {
this.fetchData();
}
renderTableData() {
return( this.state.Houses.map((house, index) => {
<tr key={index}>
<td>{house.Id}</td>
<td>{house.Country}</td>
<td>{house.Address}</td>
<td>{house.Description}</td>
<td>{house.Photo}</td>
<td>{house.Price}</td>
</tr>
}))
}
fetchData = () => {
fetch('./AllHouses')
.then(rsp => rsp.json())
.then(allHouses => {
this.setState({ Houses: allHouses });
}).catch(
function (error) { console.log(error.message); }
);
console.log(this.state.Houses);
}
render() {
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Country</th>
<th>Address</th>
<th>Description</th>
<th>Photo</th>
<th>Price</th>
</tr>
</thead>
<tbody>
**{this.renderTableData() }**
</tbody>
</table>
);
}
}
ReactDOM.render(<DataTable />, document.getElementById('content'));
add return before <tr key={index}> OR wrap the tr with () instead of {}.
renderTableData() {
return this.state.Houses.map((house, index) => {
return <tr key={index}>
<td>{house.Id}</td>
<td>{house.Country}</td>
<td>{house.Address}</td>
<td>{house.Description}</td>
<td>{house.Photo}</td>
<td>{house.Price}</td>
</tr>
})
}
you could use the bind function but I recommend you use arrow functions directly.
You could call the array state.Houses on the jsx directly executing the map if you want, and then call the function renderTableData just like this:
import React, { Component } from 'react';
class StackOverflow extends Component {
state = {
Houses: [],
};
componentDidMount() {
// Data example
this.setState({
Houses: [
{
id: 1,
Country: 'Country 1',
Address: 'address 1',
Description: 'Description 1',
Photo: 'Photo 1',
Price: 'Price 1',
},
{
id: 2,
Country: 'Country 2',
Address: 'address 2',
Description: 'Description 2',
Photo: 'Photo 2',
Price: 'Price 2',
},
{
id: 3,
Country: 'Country 3',
Address: 'address 3',
Description: 'Description 3',
Photo: 'Photo 3',
Price: 'Price 3',
},
],
});
}
renderTableData(house, index) {
return (
<tr key={index}>
<td>{house.id}</td>
<td>{house.Country}</td>
<td>{house.Address}</td>
<td>{house.Description}</td>
<td>{house.Photo}</td>
<td>{house.Price}</td>
</tr>
);
}
render() {
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Country</th>
<th>Address</th>
<th>Description</th>
<th>Photo</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{this.state.Houses.map((house, index) =>
this.renderTableData(house, index)
)}
</tbody>
</table>
);
}
}
export default StackOverflow;
it's much better organized because only you have HTML code in the renderTableData, after if you want you can export that <tr .... /tr> on a different component and call it on that function.
It's going to be cleaner and reusable your code.
Regards

ReactJS - Adding value on specific table row

I created a react js app and have a table and it contains a button "Add Available Day" when I click it checkbox with days will show and when I choose a day it will automatically put in the table, however instead of updating specific row, changes are applied in all row. What I want to happen is for example I click add available day in first row then first row data must be updated not second and third row
This is my code:
import React from 'react';
import { Table, Button } from 'react-bootstrap';
const personData = [
{ id: 1, firstName: 'test1', lastName: 'test', day: [] },
{ id: 2, firstName: 'Jane', lastName: 'Doe', day: [] },
{ id: 3, firstName: 'John', lastName: 'Doe', day: [] },
{ id: 4, firstName: 'Clint', lastName: 'test', day: [] }
]
export default class App extends React.Component {
constructor() {
super();
this.state = {
day: [],
isSelectDay: false,
person: personData
}
}
handleSelectDay = (event) => {
let dayArr = [...this.state.day]
const value = event.target.value
const index = dayArr.findIndex(day => day === value);
if (index > -1) {
dayArr = [...dayArr.slice(0, index), ...dayArr.slice(index + 1)]
} else {
dayArr.push(value)
}
this.setState({ day: dayArr });
}
handleAddDay = () => {
this.setState({ isSelectDay: true })
}
render() {
const { isSelectDay, day } = this.state
const dayOptions = ["Monday, ", "Tuesday, ", "Wednesday", "Thursday, ", "Friday"].map((cur, ind) => {
return (
<div key={ind} className="checks" >
<label>
<input type="checkbox" name={cur} value={cur}
onChange={this.handleSelectDay} />{cur}
</label>
</div>
)
})
return (
<>
<Table striped bordered hover>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Days Available</th>
</tr>
</thead>
<tbody>
{this.state.person.length > 0 ? (
this.state.person.map((person) => (
<tr key={person.id}>
<td>{person.firstName}</td>
<td>{person.lastName}</td>
<td>{day}<Button variant="success" onClick={this.handleAddDay}>Add Available Day</Button></td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No Data</td>
</tr>
)}
</tbody>
</Table>
<div style={{ display: isSelectDay ? 'block' : 'none' }}>
{dayOptions}
</div>
</>
)
}
}
Is this something you're after?
Demo
Full Code
I changed isSelectDay to personSelected so when you click 'Add Available Day' it'll switch to the correct person object from personData. I then used this to update the people object in the state (a copy of personData) to add/remove days from day array. The day array was then used to output the days.
import React from "react";
import { Table, Button } from "react-bootstrap";
var personData = [
{ id: 1, firstName: "test1", lastName: "test", day: [] },
{ id: 2, firstName: "Jane", lastName: "Doe", day: [] },
{ id: 3, firstName: "John", lastName: "Doe", day: [] },
{ id: 4, firstName: "Clint", lastName: "test", day: [] }
];
export default class App extends React.Component {
constructor() {
super();
this.state = {
personSelected: null,
people: personData
};
}
handleSelectDay = (event) => {
let dayArr = [...this.state.personSelected.day];
const value = event.target.value;
const index = dayArr.findIndex((day) => day === value);
if (index > -1) {
dayArr = [...dayArr.slice(0, index), ...dayArr.slice(index + 1)];
} else {
dayArr.push(value);
}
let newPeople = this.state.people;
newPeople.find((x) => x === this.state.personSelected).day = dayArr;
this.setState({ people: newPeople });
};
handleAddDay = (person) => {
this.setState({ personSelected: person });
document
.querySelectorAll("input[type=checkbox]")
.forEach((el) => (el.checked = false));
};
render() {
const { personSelected } = this.state;
const dayOptions = [
"Monday, ",
"Tuesday, ",
"Wednesday",
"Thursday, ",
"Friday"
].map((cur, ind) => {
return (
<div key={ind} className="checks">
<label>
<input
type="checkbox"
name={cur}
value={cur}
onChange={this.handleSelectDay}
/>
{cur}
</label>
</div>
);
});
return (
<>
<Table striped bordered hover>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Days Available</th>
</tr>
</thead>
<tbody>
{this.state.people.length > 0 ? (
this.state.people.map((person) => (
<tr key={person.id}>
<td>{person.firstName}</td>
<td>{person.lastName}</td>
<td>
{person.day}
<Button
variant="success"
onClick={() => this.handleAddDay(person)}
>
Add Available Day
</Button>
</td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No Data</td>
</tr>
)}
</tbody>
</Table>
{personSelected !== null && (
<div style={{ display: "block" }}>{dayOptions}</div>
)}
</>
);
}
}

Resources