how to display table rows in ReactJS using Map function - javascript

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>
)
}

Related

Return a dynamic table using react.js

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>
);

Applying Filter after Fetching data from api in React

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} />

Add items in different tables in react?

Here is my code :
return (
<div className="container">
<div class="col-md-12 ">
<div class ="row">
{
tableList.map(table => {
return(
<div className="item col-md-6 col-lg-3" key={table}>
<div>{table}</div>
<div className="content">
<div className="data">
<div class="col-md-6 col-lg-3 ">
<table className="item" class="auto-index" >
<thead >
<tr>
<th>#</th>
<th>Item</th>
<th>Quantity</th>
</tr>
</thead>
<tbody >
{
buyItems.map(item => {
return(
<tr key={item}>
<td></td>
<td>{item}</td>
<td className="text-middle">
1
</td>
</tr>
)
})
}
</tbody>
</table>
</div>
</div>
<button onClick={(e)=> this.removeTable(table)} type="button" className="btn btn-default btn-sm">
Remove
</button>
</div>
</div>
)
})
}
</div>
</div>
</div>
);
I want to add different items in different tables but items are duplicated in all table please help me guys. I am not so good at this java script so please you can help me by telling me how to post different item in the multiple table.
declare a store add put your list in it and send this store to all of your components which you want to use the list then just add items to your list and your tables all updated with new data or create master component which it has a state (your list) and pass via props to all of your components, if you have one component and multiple tables you can add the list in your state and add items with setState function and use it in your tables
Example :
--store
export class YourStore{
#computed get yourRows(){
return this.yourlList.map(item => {
return (
<tr key={item}>
<td></td>
<td>{item}</td>
<td className="text-middle">
1
</td>
</tr>
)
})
}
#observable yourList = []
#action addItemToList(data){
this.yourList.push(data)
}
}
--component render
<table>
<thead >
<tr>
<th>#</th>
<th>Item</th>
<th>Quantity</th>
</tr>
</thead>
<tbody >
{this.props.yourstore.yourRows}
</tbody>
</table>
Is this what your expectation? The below code will render a table for each item in the buyItems
return (
<div className="container">
<div class="col-md-12 ">
<div class ="row">
{tableList.map(table => {
return(
<div className="item col-md-6 col-lg-3" key={table}>
<div>{table}</div>
<div className="content">
<div className="data">
<div class="col-md-6 col-lg-3 ">
{buyItems.map(item => (
<table className="item" class="auto-index" >
<thead>
<tr>
<th>#</th>
<th>Item</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr key={item}>
<td></td>
<td>{item}</td>
<td className="text-middle">1</td>
</tr>
</tbody>
</table>
))}
</div>
</div>
<button onClick={(e)=> this.removeTable(table)} type="button" className="btn btn-default btn-sm">
Remove
</button>
</div>
</div>
)
})
}
</div>
</div>
</div>
);

How to use v-for in nested loops?

I am trying to filter a JSON object (the object is named 'post' in my example) using the VueJs2 framework consuming a data object from a Wordpress REST API. I have nested arrays (meta data tags) associated with my posts that I want to filter/search through when the user types a search query in my input element:
JSFIDDLE link
HTML:
<div id="app" class="container" style="padding-top: 2em;">
<input v-model="searchText">
<table class="table table-striped" v-if="posts">
<thead>
<tr>
<th>Title</th>
<th>Product Type</th>
</tr>
</thead>
<tr v-for="post in itemsSearched">
<td>{{post.title.rendered}}</td>
<!-- this part is probably not correct -->
<td v-for="post._embedded['wp:term'][1] in itemsSearched"></td>
</tr>
</table>
</div>
JS:
var vm = new Vue({
el: '#app',
data: {
message: 'hello world',
searchText: '',
posts: []
},
computed : {
itemsSearched : function(){
var self = this;
if( this.searchText == ''){
return this.posts;
}
return this.posts.filter(function(post){
return post.title.rendered.indexOf(self.searchText) >= 0;
//what to put here to filter the tags ??
});
}
},
created: function(){
$.get('https://wordpress-dosstx.c9users.io/wp-json/wp/v2/products/' + '?_embed=true')
.done(function(data) {
vm.posts = data;
});
}
});
If you can provide some advice on how to proceed that would be great. Thank you.
I updated your fiddle. You need to loop through the item of the array not the entire searched array.
<div id="app" class="container" style="padding-top: 2em;">
<input v-model="searchText">
<table class="table table-striped" v-if="posts">
<thead>
<tr>
<th>Title</th>
<th>Product Type</th>
<th>Tags</th>
</tr>
</thead>
<tr v-for="post in itemsSearched">
<td>
<a :href="post.link" target="_blank">
<img :src="post._embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url"
style="width:75px;height:75px;"/>
</a>
</td>
<td>
<a :href="post.link" target="_blank" v-html="post.title.rendered"></a><br/>
<div v-html="post.content.rendered"></div>
</td>
<td v-for="item in post._embedded['wp:term']">
<div v-for="subItem in item">
<a :href="subItem.link">{{subItem.name}}</a>
</div>
</td>
</tr>
</table>
</div>
<div v-for="item in parentObject">
<div v-for="item2 in item.childObject1">
<div v-for="item3 in item2.chileObject2"></div>
</div>
</div>
i am creating a something like this
parent
-name:
--childObject1
--mySon
---childObject2
---myGrandChild

Render a table in the rows of another table in react

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.

Categories

Resources