How to map JSON data as a table in React - reactjs

I'm trying to display data after fetching it, but that does not work :
import React, { Component } from "react";
import { Table, Button, ButtonToolbar } from "react-bootstrap";
const URL = "http://localhost:51644/api/";
let passedAthleteId = 0;
let passedAthleteSessionId = 0;
class AthleteTrainingSession extends Component {
constructor(props) {
super(props);
this.state = {
athleteTrainingSession: [],
discussions: [],
warmups: [],
workouts: [],
stretchings: [],
};
}
componentDidMount() {
this.fetchAthleteTrainingSession();
}
componentDidUpdate() {
this.fetchAthleteTrainingSession();
}
fetchAthleteTrainingSession = () => {
fetch(URL + `Coaches/4/Athletes/1/AthleteSessions/4`)
.then((response) => response.json())
.then((data) => {
this.setState({
athleteTrainingSession: data,
});
});
};
render() {
const {
athleteTrainingSession,
discussions,
warmups,
workouts,
stretchings,
} = this.state;
passedAthleteId = this.props.match.params.athleteId;
passedAthleteSessionId = this.props.match.params.athleteSessionId;
this.discussions = this.state.athleteTrainingSession.Discussions;
this.warmups = this.state.athleteTrainingSession.Warmups;
this.workouts = this.state.athleteTrainingSession.Workouts;
this.stretchings = this.state.athleteTrainingSession.Stretchings;
console.log(athleteTrainingSession);
console.log(this.warmups);
return (
<React.Fragment>
<div>
<h2 className="mt-2">
Programme d'entraînement :{" "}
{athleteTrainingSession.TrainingProgramName}
</h2>
<h4>
Séance d'entraînement : {athleteTrainingSession.TrainingSessionName}
</h4>
</div>
<div>
<ButtonToolbar>
<Button variant="primary">Ajouter</Button>
<Button variant="secondary">Discussion</Button>
</ButtonToolbar>
<h4>Échauffement</h4>
<Table className="mt-4" striped bordered hover size="sm">
<thead>
<tr className="d-flex">
<th className="col-6">Exercice</th>
<th className="col-6">Options</th>
</tr>
</thead>
<tbody>
{warmups.map((warm) => (
<tr className="d-flex" key={warm}>
<td className="col-6">{warm.ExerciseName}</td>
<td className="col-6">
<ButtonToolbar>
<Button className="mr-2" variant="info">
Modifier
</Button>
<Button className="mr-2" variant="danger">
Supprimer
</Button>
</ButtonToolbar>
</td>
</tr>
))}
</tbody>
</Table>
</div>
</React.Fragment>
);
}
}
export default AthleteTrainingSession;
athleteTrainingSession contains the fetched data, and warmups is a sub-object for athleteTrainingSession.
When I console.log(warmups), I can see that it does contain data, but I cannot display it in the table.
athleteTrainingSession contains the fetched data, and warmups is a sub-object for athleteTrainingSession.
When I console.log(warmups), I can see that it does contain data, but I cannot display it in the table.

I think you have misconception of using state in component.
You're able to console the warmups because in your code you console.log(this.warmups), but you render the map with this.state.warmups
you should setState all of the data that you get from fetch, i.e:
fetchAthleteTrainingSession = () => {
fetch(URL + `Coaches/4/Athletes/1/AthleteSessions/4`)
.then((response) => response.json())
.then((data) => {
this.setState({
athleteTrainingSession: data,
warmups: data.Warmups,
workouts: data.Workouts,
discussions: data.Discussions,
stretchings: data.Stretchings,
});
});
};
by doing this way, now you can access the warmups data from this.state.warmups then render it
render() {
const {
athleteTrainingSession,
discussions,
warmups,
workouts,
stretchings,
} = this.state;
return (
<React.Fragment>
...
{warmups.map((warm) => (
<tr className="d-flex" key={warm}>
<td className="col-6">{warm.ExerciseName}</td>
<td className="col-6">
<ButtonToolbar>
<Button className="mr-2" variant="info">
Modifier
</Button>
<Button className="mr-2" variant="danger">
Supprimer
</Button>
</ButtonToolbar>
</td>
</tr>
))}
...
</React.Fragment>
)
}

Related

uploading data to table getting no result

hello iam following mosh hamedani course at some point i got stuck in uploading data in table
this is my table where title and genre is uploading where in stock and rate these are number not string are not uploading here is my table body
class TableBody extends Component {
render() {
const {data,columns} = this.props
console.log({data,columns})
return ( <tbody>
{data.map(item => <tr key={item._id}>
{columns.map(column => <td key={item._id + (column.path || column.key)}>{_.get(item,column.path)}</td>)}
</tr>
)}
</tbody>
);
}
}
data and columns are coming from movietable component here is the code
class MovieTable extends Component {
columns =[
{ path:'title',label:'Title'},
{ path:'genre.name',label:'Genre'},
{ path:'numberInstock',label:'stock'},
{ path:'dailyReantalRate',label:'Rate'},
{ key: 'like' },
{key: 'delete' }
];
render() {
const {movies, onDelete,onSort ,onLike,sortColumn,onAdd,deleted} = this.props;
return (
<table className="table">
<TableHeader columns={this.columns} sortColumn={sortColumn} onSort={onSort}/>
<TableBody data={movies} columns={this.columns}/>
<tbody>
{movies.map((movie) => (
<tr key={movie._id}>
<td>{movie.title}</td>
<td>{movie.genre.name}</td>
<td>{movie.numberInStock}</td>
<td>{movie.dailyRentalRate}</td>
<td>
{" "}
<Like
liked={movie.liked}
onClick={() => onLike(movie)}
/>{" "}
</td>
<td
onClick={() => onDelete(movie._id)}
className="btn btn-danger btn-outline-warning btn-sm active "
>
Remove
</td>
</tr>
))}
</tbody>
<tbody>
{deleted.map((movie) => (
<tr key={movie._id}>
<td>{movie.title}</td>
<td>{movie.genre.name}</td>
<td>{movie.numberInStock}</td>
<td>{movie.dailyRentalRate}</td>
<td>
{" "}
<Like />{" "}
</td>
<td
onClick={() => onAdd (movie._id)}
className="btn btn-danger btn-outline-primary btn-sm active "
>
ADD
</td>
</tr>
))}
</tbody>
</table>
);
}
}
movies from props coming from its parent movies component here is movies component code
class Movies extends Component {
state = {
movies:[],
deleted: [],
genres:[],
pageSize: 9,
currentPage:1,
sortColumn:{
path:'title',
order:'asc'
}
};
componentDidMount(){
const genres =[{ _id:"",name:'All Genres'},...getGenres()]
this.setState({
movies:getMovies(),
genres
})
}
handleDelete = (_id) => {
const movie = this.state.movies.find((x) => x._id === _id);
this.setState({ deleted: [...this.state.deleted, movie] });
this.setState({ movies: this.state.movies.filter((x) => x._id !== _id) });
};
handleLike = (m) => {
const movies = [...this.state.movies];
const index = movies.indexOf(m);
movies[index] = { ...movies[index] };
movies[index].liked = !movies[index].liked;
this.setState({ movies });
};
handleReinstate = (_id) => {
const movie = this.state.deleted.find((movie) => movie._id === _id);
this.setState({ movies: [...this.state.movies, movie] });
this.setState({
deleted: this.state.deleted.filter((movie) => movie._id !== _id),
});
};
handleGenreSelect = genre => {
this.setState({selectedGenre:genre, currentPage:1})
}
handleSort= sortColumn =>{
this.setState({sortColumn});
}
render() {
const { pageSize,currentPage,sortColumn,selectedGenre,movies:allMovies,deleted} = this.state;
const filtered = selectedGenre && selectedGenre._id ? allMovies.filter(m=>m.genre._id === selectedGenre._id ): allMovies;
const sorted = _.orderBy(filtered, [sortColumn.path],[sortColumn.order]);
const movies = paginate(sorted,currentPage,pageSize)
return (
<div className="row">
<div className="col-2">
<ListGroup items={this.state.genres} selectedItem={this.state.selectedGenre} onItemSelect={this.handleGenreSelect}/>
</div>
<div className="col">
<div className={this.getbadgesClasses()}> <p>there are {filtered.length} movies in our data base</p> </div>
<MovieTable
movies={movies}
onSort={this.handleSort}
onDelete={this.handleDelete}
onLike={this.handleLike}
deleted={deleted}
onAdd={this.handleReinstate}/>
<Pagination
itemCount={filtered.length}
pageSize={pageSize}
sortColumn={sortColumn}
onPageChange={this.handlePageChange}
currentPage={currentPage}
/>
</div>
</div>
);
}
getbadgesClasses() {
let classes = " badge m-2 badge-";
classes += this.state.movies.length === 0 ? "warning" : "primary";
return classes;
}
handlePageChange = (page) => {
this.setState({currentPage: page})
};
}
this is my console.log
i have give aerong path to Columns array its like spelling mistake in path

how to react-js-pagination implement with react hook data table

How to integrate pagination code with hooks method data table with. im using react-js-pagination nmp package but there is no one explanation for implement with hook method program.
This my data table code:
import React, { useEffect, useState } from 'react';
import axios from 'axios'
import 'bootstrap/dist/css/bootstrap.min.css';
import {Link} from 'react-router-dom';
const ProTable = () => {
const [data, setData] = useState([]);
useEffect(() => {
loadData();
}, []);
const loadData = async() => {
axios.get('http://localhost:5000/api/clientgetdata')
.then(response => {
setData(response.data.map);
}
const delPro = (item,e) => {
var option = window.confirm(`Are you sure to delete ${e.clientName} OF ${item.projectName}`)
if(option){
const check = axios.delete(`http://localhost:5000/api/clientdelpro/${e.clientName}/${item.projectName}`).then(res => {
//console.log(clientname)
window.location.reload(false)
})
}
}
return (
<>
<div className="row addButton">
<div className="col-lg-1">
<Link
className="btn btn-outline-primary mr-2"
to={'/client/addpro'}
>New</Link>
</div>
<div className="col-lg-1">
{/* <button variant="primary" >Delete</button> */}
</div>
</div>
<div className="row hrtable">
<div className="col-lg-10 col-sm-6 col-md-6">
<div className="table-responsive tcenter" >
<table className="table table-bordered table-hover table-sm">
<thead className="thead-dark">
<tr>
<th scope="col"><input type="checkbox" /></th>
<th scope="col">Client Name</th>
<th scope="col">Project Name</th>
<th scope="col">Status</th>
<th>Action</th>
</tr>
</thead>
{ (data.length > 0) ? data.map( e => {
return (
<>
{e.project.map(item=> {
return (
<tbody>
<tr>
<th scope="row">
<input type="checkbox"/>
</th>
<td><ul>{e.clientName}</ul></td>
<td><ul>{item.projectName}</ul></td>
<td><ul>{item.proStatus}</ul></td>
<td>
<Link
className="btn btn-outline-primary mr-2"
to={`/project/edit/${e.clientName}/${item.projectName}`} >
Edit
</Link>
<button
className="btn btn-danger"
onClick={() => delPro(item,e)}>
Delete
</button>
</td>
</tr>
</tbody>
);
})}
</>
);
}) : <tr><td colSpan="5">No Records Found</td></tr> }
</table>
</div>
</div>
</div>
</>
);
}
export default ProTable;
This is Reaci-js-pagination code.
I am trying to follow this tutorial to create a pagination in my application https://www.npmjs.com/package/react-js-pagination#usage
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Pagination from "react-js-pagination";
require("bootstrap/less/bootstrap.less");
class App extends Component {
constructor(props) {
super(props);
this.state = {
activePage: 15
};
}
handlePageChange(pageNumber) {
console.log(`active page is ${pageNumber}`);
this.setState({activePage: pageNumber});
}
render() {
return (
<div>
<Pagination
activePage={this.state.activePage}
itemsCountPerPage={10}
totalItemsCount={450}
pageRangeDisplayed={5}
onChange={this.handlePageChange.bind(this)}
/>
</div>
);
}
}
plz help me how integrate both code
Try by converting it into hooks
const [state, setState] = React.useState({activePage: 15});
const handlePageChange=(pageNumber) => {
setState({activePage: pageNumber});
// make api call for next page
}
return (
<div>
<Pagination
activePage={state.activePage}
itemsCountPerPage={10} // pass your fixed item per pages
totalItemsCount={450} // total item -> per-page * no of page
pageRangeDisplayed={5}
onChange={handlePageChange}
/>
</div>
);

add a click event after deleting list

i have created a fuction in which onClick i delete movie but I also want to add a add button by which clicking on add button i get my deleted movie back
here is my code
class Movies extends Component {
state = {
movies: getMovies(),
};
handleDelete=(movi)=>{
const movies = this.state.movies.filter(m=> m._id !== movi._id)
this.setState({movies})
}
render() {
return (
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Stock</th>
<th>Rate</th>
<th></th>
</tr>
</thead>
<tbody>
{this.state.movies.map((movie) => (
<tr key={movie._id}>
<td >{movie.title}</td>
<td >{movie.genre.name}</td>
<td >{movie.numberInStock}</td>
<td >{movie.dailyRentalRate}</td>
<td onClick={()=>this.handleDelete(movie)} className="btn btn-danger btn-outline-warning btn-sm active ">Remove</td>
</tr>
))}
</tbody>
</table>
);
}
}
You need to somehow keep track of the movies that you are deleting so that you can reinstate them... 3 Components (App - parent, Movie & Deleted)
Here is your App:
export default class App extends Component {
state = { movies: getMovies(), deleted: [] };
handleDelete = id => {
const movie = this.state.movies.find(movie => movie.id === id);
this.setState({ deleted: [...this.state.deleted, movie] });
this.setState({
movies: this.state.movies.filter(movie => movie.id !== id)
});
};
handleReinstate = id => {
const movie = this.state.deleted.find(movie => movie.id === id);
this.setState({ movies: [...this.state.movies, movie] });
this.setState({
deleted: this.state.deleted.filter(movie => movie.id !== id)
});
};
render() {
return (
<div>
<h1>Movies</h1>
{this.state.movies.map(movie => {
return (
<Movie
key={movie.id}
movie={movie}
handleDelete={this.handleDelete}
/>
);
})}
<hr />
<h1>Deleted</h1>
{this.state.deleted.map(movie => {
return (
<Deleted
key={movie.id}
movie={movie}
handleReinstate={this.handleReinstate}
/>
);
})}
</div>
);
}
}
Here is your Movie:
export default function Movie({ movie, handleDelete }) {
return (
<div>
<h4>{movie.title}</h4>
<button onClick={() => handleDelete(movie.id)}>Delete</button>
</div>
);
}
Here is your Deleted / Reinstate:
export default function Deleted({ movie, handleReinstate }) {
return (
<div>
<h4>{movie.title}</h4>
<button onClick={() => handleReinstate(movie.id)}>Reinstate</button>
</div>
)
}
Here is a link to a live demo: https://stackblitz.com/edit/react-umffju?file=src%2FApp.js
For this type of problem, here’s what you could do. Store the deleted movies in state with something like this:
This.state={
currentMovies: [list of movies],
deletedMovies: [list of movies]
}
Have an array that stores Json objects like your movies. Then have a function for storing movies that have been deleted:
const deleteMoviesArray=[]
deleteMovie(movieData){
deleteMoviesArray.push(movieData);
This.setState({
deletedMovies: deletedMoviesArray
})
};
Now you have stored your deleted movies. To retrieve your deleted movies, you might use a drop down box something like this:
<select>
{
This.state.deletedMovies.map(data =>(
<option> {movie.title}</option>
))
}
</select>
And once you select one, do a similar thing to what you did with deleted movies, add a movie back to an array of available movies.
If you need your list of deleted movies to persist past a page refresh, you might consider storing that data in session storage:
window.sessionStorage.setItem(‘deletedMovieArray’, [list of movie objects])
And get them
window.sessionStorage.getItem(‘deletedMovieArray’)

How to change the text of a single button in Reactjs

I am having a List of Jobs with Approve button.
Expected Result
Whenever the Approve button next to a Job is clicked, the Job should be approved and the button text should say Approved.
Original Outcome
The text of all the buttons gets changed to Approved, but only a single Job gets approved, i.e. the job the was actually approved. Also the text stays approved for all the jobs until the page is refreshed.
export default class ProfilePage extends Component {
constructor() {
super();
this.state = {
allJobs: [],
loading: true,
newLoading: false,
valueApprove: "Approve",
_id: ""
};
this.handleApproveJob = this.handleApproveJob.bind(this);
}
componentDidMount() {
var apiUrl = `http://localhost:5000/admin/pendingJobs`;
fetch(apiUrl)
.then(response => {
return response.json();
})
.then(data => {
let allJobsFromApi = data.PendingJobs.map(job => {
return {
jobmainid: job._id,
companyName: job.companyNane,
contactPerson: job.contactPerson,
jobTitle: job.jobTitle,
jobDescription: job.description,
jobCategory: job.category.name,
jobDuration: job.duration,
descriptionLink: job.descriptionLink,
status: job.status
}
})
this.setState({ allJobs: allJobsFromApi, loading: false });
})
.catch(error => {
console.log(error);
})
}
handleApproveJob(e) {
this.setState({
newLoading: true
})
e.preventDefault();
var jobId = e.target.getAttribute('jobId');
console.log(jobId);
const job = {
approvedJobId: jobId
};
approveJob(job).then((res, err) => {
if (res) {
this.setState({
newLoading: false,
valueApprove: "Approved"
})
} else {
this.setState({
loading: false,
message: "some error occured"
})
}
})
}
render() {
const { newLoading, valueApprove } = this.state;
return (
<div className="tile-body">
{loading ? <div className="col-md-4 offset-md-4"><img src=
{LoadingSpinner} /></div> : <table
className="table table-hover table-bordered table-responsive"
id="sampleTable"
style={{ border: "none" }}
>
<thead>
<tr>
<th>Company Name</th>
<th>Contact Person At Company</th>
<th>Job Title</th>
<th>Job Description</th>
<th>Job Description Link</th>
<th>Category</th>
<th>Duration</th>
<th>Edit</th>
<th>Approve</th>
</tr>
</thead>
<tbody>
{this.state.allJobs.map((job) =>
<tr key={job.jobmainid}>
<td>{job.companyName}</td>
<td>{job.contactPerson}</td>
<td>{job.jobTitle}</td>
<td>{job.jobDescription}</td>
<td>
{job.descriptionLink}
</td>
<td>{job.jobCategory}</td>
<td>{job.jobDuration}</td>
<td>
<Link to={"/admin/editJob/" + job.jobmainid}>
<button className="btn btn-warning">Edit</button>
</Link>
</td>
<td>
<button
type="submit"
className="btn btn-success"
jobId={job.jobmainid}
onClick={this.handleApproveJob}
>
{ newLoading ? <ButtonLoading /> : valueApprove }
</button>
</td>
</tr>
)}
</tbody>
</table>}
</div>
The code for aproveJob() function
//Approve Job
export const approveJob = job => {
return axios.post("http://localhost:5000/admin/approveJob", {
_id: job.approvedJobId
})
.then(response => {
return response.data;
})
.catch(err => {
console.log(err);
});
}
Right now you are only storing a single variable with the approved state. Instead we need one per button.
You could do something like the below code.
After getting the array jobs from the server inject a value approved: false
On button click find and update that item in your state with approved: true
I'm not certain the code below runs but it will point you in the right direction.
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
export const approveJob = (job) => {
return fetch('http://localhost:5000/admin/approveJob', {
_id: job.approvedJobId
})
.then((response) => {
return response.data
})
.catch((err) => {
console.log(err)
})
}
export default class ProfilePage extends Component {
constructor(props) {
super(props)
this.state = {
allJobs: [],
loading: true,
newLoading: false
}
this.handleApproveJob = this.handleApproveJob.bind(this)
}
componentDidMount() {
const apiUrl = `http://localhost:5000/admin/pendingJobs`
fetch(apiUrl)
.then((response) => {
return response.json()
})
.then((data) => {
const allJobsFromApi = data.PendingJobs.map((job) => {
return {
jobmainid: job._id,
companyName: job.companyNane,
contactPerson: job.contactPerson,
jobTitle: job.jobTitle,
jobDescription: job.description,
jobCategory: job.category.name,
jobDuration: job.duration,
descriptionLink: job.descriptionLink,
status: job.status,
approved: false
}
})
this.setState({ allJobs: allJobsFromApi, loading: false })
})
.catch((error) => {
console.log(error)
})
}
handleApproveJob(e, index) {
e.preventDefault()
this.setState({
newLoading: true
})
const jobId = e.target.getAttribute('jobId')
console.log(jobId)
const job = {
approvedJobId: jobId
}
approveJob(job).then((res) => {
if (res) {
const newAllJobs = this.state.allJobs
newAllJobs[index].approved = true
this.setState({
newLoading: false,
valueApprove: 'Approved',
allJobs: newAllJobs
})
} else {
this.setState({
loading: false,
message: 'some error occured'
})
}
})
}
render() {
const { loading, newLoading, valueApprove, allJobs } = this.state
return (
<div className="tile-body">
{loading ? (
<div className="col-md-4 offset-md-4">
<img src={LoadingSpinner} />
</div>
) : (
<table
className="table table-hover table-bordered table-responsive"
id="sampleTable"
style={{ border: 'none' }}
>
<thead>
<tr>
<th>Company Name</th>
<th>Contact Person At Company</th>
<th>Job Title</th>
<th>Job Description</th>
<th>Job Description Link</th>
<th>Category</th>
<th>Duration</th>
<th>Edit</th>
<th>Approve</th>
</tr>
</thead>
<tbody>
{allJobs.map((job, index) => (
<tr key={job.jobmainid}>
<td>{job.companyName}</td>
<td>{job.contactPerson}</td>
<td>{job.jobTitle}</td>
<td>{job.jobDescription}</td>
<td>
<a href={job.descriptionLink} target="_blank">
{job.descriptionLink}
</a>
</td>
<td>{job.jobCategory}</td>
<td>{job.jobDuration}</td>
<td>
<Link to={'/admin/editJob/' + job.jobmainid}>
<button className="btn btn-warning">Edit</button>
</Link>
</td>
<td>
<button
type="button"
className="btn btn-success"
jobId={job.jobmainid}
onClick={(e) => this.handleApproveJob(e, index)}
>
{newLoading ? <ButtonLoading /> : valueApprove}
</button>
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
)
}
}
try this.
handleApproveJob(e) {
this.setState({
newLoading: true
});
e.preventDefault();
var jobId = e.target.getAttribute('jobId');
console.log(jobId);
const job = {
approvedJobId: jobId
};
let self = this;
approveJob(job).then((res, err) => {
if (res) {
self.setState({
newLoading: false,
valueApprove: "Approved"
})
} else {
self.setState({
loading: false,
message: "some error occured"
})
}
})
}
<button type="submit" className="btn btn-success" jobId={job.jobmainid} onClick={this.handleApproveJob}>
{ this.state.newLoading ? <ButtonLoading /> : this.state.valueApprove }
</button>
I hope I've been there for you. Let me know.
Three things are there.
you need to add approve: false to every item in the jobs
On clicking approve button of any job, you need to pass index of that job in the approveJob(index) function.
Depending on the index value (which was passed in approveJob(index)) you need to updated the particular job in the job array in the state.
Just update the render function code for approve button, as you need change text on clicking button
render() {
const { loading, newLoading, valueApprove, allJobs } = this.state
return (
<div className="tile-body">
{loading ? (
<div className="col-md-4 offset-md-4">
<img src={LoadingSpinner} />
</div>
) : (
<table
className="table table-hover table-bordered table-responsive"
id="sampleTable"
style={{ border: 'none' }}
>
<tbody>
{allJobs.map((job, index) => (
<tr key={job.jobmainid}>
<td>
<button
type="button"
className="btn btn-success"
jobId={job.jobmainid}
onClick={(e) => this.handleApproveJob(e, index)}
>
{job.approved ? "approved" : "approve"}
</button>
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
)
}
}

Open Modal from Table Row in React

openBookDetails sets isBookDetailsOpen: true which should change the className in showHideClassName to modal display-block and it should show on the screen but the modal doesn't show. However it appears in Elements in the Development tools
import React, { Component } from 'react';
import './Update.css';
import Search from '../Search/Search';
// import Modal from './Modal/Modal';
const Table = ({ data, openBookDetails }) => (
<table class="table table-hover">
<thead>
<tr class="table-primary">
<th scope="col">Title</th>
<th scope="col">Author</th>
<th scope="col">ISBN</th>
<th scope="col">No. Of Copies</th>
</tr>
</thead>
<tbody>
{data.map(row =>
<TableRow key={row.id} row={row} openBookDetails={openBookDetails}/>
)}
</tbody>
</table>
)
const TableRow = ({ row, openBookDetails }) => (
<tr class="table-light" onClick={openBookDetails}>
<th scope="row" >{row.title}</th>
<td >{row.author}</td>
<td >{row.isbn}</td>
<td >24</td>
</tr>
)
const Modal = ({ closeBookDetails, isBookDetailsOpen, children }) => {
const showHideClassName = isBookDetailsOpen ? 'modal display-block' : 'modal display-none';
return (
<div className={showHideClassName}>
<section className='modal-main'>
{children}
<button
onClick={closeBookDetails}
>
Close
</button>
</section>
</div>
);
};
class Update extends Component{
constructor(props) {
super(props);
this.state = {
value: '',
suggestions: [],
setOfAllBooks: [],
searchedBooks: [],
isBookDetailsOpen: false,
};
this.openBookDetails = this.openBookDetails.bind(this);
this.setTableData = this.setTableData.bind(this);
}
setTableData(searchedBook){
this.setState({searchedBooks: searchedBook})
console.log(this.state.searchedBooks)
}
openBookDetails(){
console.log('openBookDetails')
this.setState({ isBookDetailsOpen: true})
}
closeBookDetails(){
this.setState({ isBookDetailsOpen: false})
}
render(){
return(
<main>
<div class="container">
<Search state={this.state} setTableData={this.setTableData} />
<Table data={this.state.searchedBooks} openBookDetails={this.openBookDetails}/>
<Modal isBookDetailsOpen={this.state.isBookDetailsOpen} closeBookDetails={this.closeBookDetails} />
{/* <Modal /> */}
</div>
</main>
)
}
}
export default Update;

Resources