Im trying to create a dynamic table using react.
Here is what I have so far...
DataTable.js
import React from 'react'
import data from '../data/customerData.json'
import '../styles/dataTable.css'
const DataTable = () => {
return (
<div>
{data.map(dat => {
return (
<div>
<table className='data-table-container'>
<tr>
<th>Customer Name</th>
<th>Phone Number</th>
<th>Loan Vehicle</th>
<th>Time Out</th>
<th>Time Due</th>
</tr>
<tr>
<td>{dat.CustomerName}</td>
<td>{dat.PhoneNumber}</td>
<td>{dat.LoanVehicle}</td>
<td>{dat.TimeOut}</td>
<td>{dat.TimeDue}</td>
</tr>
</table>
</div>
);
})}
</div>
);
}
export default DataTable
Home.js
import React, { useState } from 'react';
import Calendar from 'react-calendar';
import DataTable from '../components/DataTable';
import '../styles/calendar.css'
const Home = () => {
const [value, onChange] = useState(new Date());
let today = new Date().toDateString()
return (
<>
<div className='date-display'>
<h3 className='current-date-display'>{today}</h3>
</div>
<Calendar onChange={onChange} value={value} />
<DataTable/>
</>
)
}
export default Home
Here is what that renders in the browser..
So currently in my DataTable.js component I am using .map to loop over the data in customerData.json which works fine. The issue I have is as you can see from the screenshot img the table headers in the <th> tags render with each loop.
My question is how can I display the <th> tags once and keep the loop to display the <td> tag content..
See expected output below..
You're creating many tables, in a loop. Instead of outputting the entire table in the .map() body, only output the rows. Keep everything else static outside of that loop:
return (
<div>
<div>
<table className='data-table-container'>
<tr>
<th>Customer Name</th>
<th>Phone Number</th>
<th>Loan Vehicle</th>
<th>Time Out</th>
<th>Time Due</th>
</tr>
{data.map(dat => {
return (
<tr>
<td>{dat.CustomerName}</td>
<td>{dat.PhoneNumber}</td>
<td>{dat.LoanVehicle}</td>
<td>{dat.TimeOut}</td>
<td>{dat.TimeDue}</td>
</tr>
);
})}
</table>
</div>
</div>
);
You can make it a little more clear for yourself by explicitly separating <thead> and <tbody> elements:
return (
<div>
<div>
<table className='data-table-container'>
<thead>
<tr>
<th>Customer Name</th>
<th>Phone Number</th>
<th>Loan Vehicle</th>
<th>Time Out</th>
<th>Time Due</th>
</tr>
</thead>
<tbody>
{data.map(dat => {
return (
<tr>
<td>{dat.CustomerName}</td>
<td>{dat.PhoneNumber}</td>
<td>{dat.LoanVehicle}</td>
<td>{dat.TimeOut}</td>
<td>{dat.TimeDue}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
You might even add a default "no records found" row when there's no data to display, just for a bit more user experience:
return (
<div>
<div>
<table className='data-table-container'>
<thead>
<tr>
<th>Customer Name</th>
<th>Phone Number</th>
<th>Loan Vehicle</th>
<th>Time Out</th>
<th>Time Due</th>
</tr>
</thead>
<tbody>
{data.length > 0 ? data.map(dat => {
return (
<tr>
<td>{dat.CustomerName}</td>
<td>{dat.PhoneNumber}</td>
<td>{dat.LoanVehicle}</td>
<td>{dat.TimeOut}</td>
<td>{dat.TimeDue}</td>
</tr>
);
}) : <tr><td colspan="5">No records found</td></tr>}
</tbody>
</table>
</div>
</div>
);
Related
I'm Fetching data from this Api https://randomuser.me/api/?results=25
I want to perform a check after getting data that if gender=Male then I want to show a Male Icon,
so how can we perform this check on Api data and return some html data like img tag or something to show icon?
Can anyone tell how can I do that?
Here is the code
function Users() {
const [Users, setUsers] = useState([])
useEffect(() => {
axios.get('https://randomuser.me/api/?results=25')
.then(Response=>{
if(Response.data){
alert("FOund")
console.log(Response.data.results)
setUsers(Response.data.results)
}else{
alert("not found")
}
})
}, [])
const displaylist = Users.map((User,index)=>{
if(User.gender==='male'){
return(
<tr>
<th scope="row">1</th>
<td><img src={User.picture.medium}></img></td>
<td>{User.name.first}</td>
<td>{User.name.last}</td>
<td>{User.location.city}</td>
<td>{User.location.state}</td>
<td>{User.email}</td>
</tr>
)
}
})
const displaylistf = Users.map((User,index)=>{
if(User.gender==='female'){
return(
<tr>
<th scope="row">1</th>
<td><img src={User.picture.medium}></img></td>
<td>{User.name.first}</td>
<td>{User.name.last}</td>
<td>{User.location.city}</td>
<td>{User.location.state}</td>
<td>{User.email}</td>
</tr>
)
}
})
return (
<div className="user">
<section id="admin" class=" px-2 px-md-5">
<div class="container-fluid border border-white rounded my-4 table-responsive">
<div class="text-center my-3">
<h1>Admin dashboard</h1>
</div>
<table class="table table-sm">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Image</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">City</th>
<th scope="col">State</th>
<th scope="col">Email</th>
<th scope="col">ICON</th>
</tr>
</thead>
<tbody>
{displaylist}
{displaylistf}
</tbody>
</table>
</div>
</section>
</div>
)
}
I think conditional rendering might help you here.
For example:
<img src={User.gender === "male" ? 'some male image src in string' : 'some female image source in string' alt={User.gender} />
I am building a Film grid that should return their Id, thumbnail, title, episode number and released date.
How can a map these values of Swapi? (Thumbnails are in img folder)
ListFilms.js Component:
import React, { Component } from "react";
class ListFilms extends Component {
render() {
const films = this.props.films;
console.log(films);
return (
<div className="row">
<table className="table table-dark">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Thumbnail</th>
<th scope="col">Film Title</th>
<th scope="col">Released Date</th>
<th scope="col">Episode Number</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{films.id}</th>
<td>
<img src={} alt={}>
</td>
<td>{films.title}</td>
<td>{films.created}</td>
<td>{films.episode_id}</td>
</tr>
</tbody>
</table>
</div>
);
}
}
export default ListFilms;
CodeSandbox Demo
You can use the below code to iterate through the list of items and get it displayed. I have moved the images to public folder to avoid webpack from having to bundle them as part of your code.
https://codesandbox.io/s/z6y768y37p
<tbody>
{ films.map((film,index) => (<tr key={film.title}>
<th scope="row">{index + 1}</th>
<td><img src={`/img/${film.title}.jpeg` width="40px"} /></td>
<td>{film.title}</td>
<td>{film.release_date}</td>
<td>{film.episode_id}</td>
</tr>)) }
</tbody>
I want to populate a table with algolia search result. I have this html
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Product</th>
<th>quantity</th>
<th>Status</th>
<th>Phone</th>
<th>Fax</th>
</tr>
</thead>
<tbody id="hits">
</tbody>
</table>
<script type="text/html" id="hit-template">
<tr id="hit">
<td>
<div class="round-img">
<img src="images/avatar/4.jpg" alt="">
</div>
</td>
<td>${{VendorName}}</td>
<td><span>iBook</span></td>
<td><span>456 pcs</span></td>
<td><span class="badge badge-success">Done</span></td>
<td><span>${{Active}}</span></td>
<td><span>${{Vendortype}}</span></td>
</tr>
</script>
and this is my js script
search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
templates: {
item: document.getElementById('hit-template').innerHTML,
empty: "We didn't find any results for the search <em>\"{{query}}\"</em>"
}
})
);
search.start();
the search is working but the table are not being properly populated. this is what is being displayed
What am I doing wrongly and how can I fix this that it is properly populated on the table?
I am using ReactJS to display a table. The rows of this table are fetched from the database. I can get only row to show but adding an additional {object.title} returns an error that object is not defined. Here is my code:
tabRow(){
if(this.state.products instanceof Array){
const roles = this.state.products.map((object, i) =>
<td>{object.id}</td>,
<td>{object.title}</td>
);
return (
<tr>{roles}</tr>
);
}
}
render(){
return (
<div>
<h1>Products</h1>
<div className="row">
<div className="col-md-10"></div>
<div className="col-md-2">
<Link to="/add-item">Create Product</Link>
</div>
</div><br />
<table className="table table-hover">
<thead>
<tr>
<td>ID</td>
<td>Product Title</td>
<td>Product Body</td>
<td width="200px">Actions</td>
</tr>
</thead>
<tbody>
{this.tabRow()}
{console.log(this.tabRow())}
</tbody>
</table>
</div>
)
}
I want to create something like this in react:
I create a renderTable and a renderInside function. Inside renderTable I call renderInside like this:
const renderInside = (slipsList) => {
if (slipsList) {
return (
<table className="table table-bordered">
<thead>
<tr>
<th className="table__header">
<div className="table__header__text">
<span className="table__header--selected">
Symbol
</span>
</div>
</th>
</tr>
</thead>
<tbody>
{slipsList.map((slip, i) =>
<tr key={i}>
<td>{slip.amount}</td>
</tr>
)}
</tbody>
</table>
);
}
return (
<div>Loading...</div>
);
};
and the renderTable is like this:
const renderTable = (slipsList) => {
if (slipsList) {
return (
<div className="table-scrollable-container">
<div className="table-scrollable">
<table className="table table-bordered">
<thead>
<tr>
<th className="table__header">
<div className="table__header__text">
<span className="table__header--selected">
Date Valeur
</span>
</div>
<div className="table__header__arrow" />
</th>
</tr>
</thead>
<tbody>
{slipsList.map((slip, i) =>
<tr key={i}>
<td className="table-sticky--first-col">
{slip.confirmationDate}
</td>
<td>
{slip.netAmountEuro}
</td>
<tr className="collapsed">
<td colSpan="10">
{renderInside(slipsList)}
</td>
</tr>
</tr>
)}
</tbody>
</table>
</div>
</div>
);
}
return (
<div>Loading...</div>
);
};
But it doesn't work. I use another two ways of doing this but I want. For every row or the main table I must put the secondary table. Any ideas of how to do this?
Try to Use this:
In renderInside method:
{slipsList.map((slip, i) => ( //added this bracket
<tr key={i}>
<td>{slip.amount}</td>
</tr>
)
)}
In renderTable method:
{slipsList.map((slip, i) => ( //added this bracket
<tr key={i}>
<td className="table-sticky--first-col">
{slip.confirmationDate}
</td>
<td>
{slip.netAmountEuro}
</td>
<tr className="collapsed">
<td colSpan="10">
{renderInside(slipsList)}
</td>
</tr>
</tr>
)
)}
One more thing, i think you need to pass slip inside {renderInside(slipsList)} method instead of slipsList.