hey all i have this array of objects
this.state = {
users :[{
userid:'1',
fullName :'eddyabikhalil',
dob:'10/03/1994',
gender:'M',
loan:[{
loanid:'1',
date:'20/7/2012',
loanValue:'100$',
},
{
loanid:'2',
date:'21/4/2014',
loanValue:'200$',
},
{
loanid:'3',
date:'20/12/2015',
loanValue:'300$',
}]
},
userid:'2',
fullName :'joe salloum',
dob:'11/04/1993',
gender:'M',
loan:[{
loanid:'4',
date:'20/7/2012',
loanValue:'500$',
},
{
loanid:'5',
date:'21/4/2017',
loanValue:'600$',
},
{
loanid:'6',
date:'20/12/2012',
loanValue:'700$',
}
],
}]
}
}
so i wrote this function to map inside of this array of object:
renderTable(userValue) {
let HTML = [];
let groupedVals = groupBy(userValue, 'userid');
let usersObj = [];
map(groupedVals, (value, key) => {
let userss = {
FullName: value.fullName,
dob: value.dob,
gender: value.gender,
loans: []
}
map(value, (subValue) => {
userss.loans.push(subValue.loanValue)
})
usersObj.push(userss);
})
map(usersObj, (val) => {
HTML.push(<tr>
<td>
{val.FullName}
</td>
<td>
{val.dob}
</td>
<td>
{val.gender}
</td>
<td>
{val.loans.join(',')}
</td>
</tr>
)
})
return HTML;
}
i want to make a table with the following fields: fullName, dob, gender and loan
i want to show that userid = 1 have multiple loan value in one td
so i created this table:
render() {
return (
<div className="container">
<table className="table table-striped">
<thead>
<tr>
<td>FullName</td>
<td>dob</td>
<td>gender</td>
<td>loans</td>
</tr>
</thead>
<tbody>
{
this.state.users &&
this.renderTable(this.state.users)
}
</tbody>
</table>
</div>
);
}
any help guys? thanks in advance
render() {
return (
<div className="container">
<table className="table table-striped">
<thead>
<tr>
<td>FullName</td>
<td>dob</td>
<td>gender</td>
<td>loans</td>
</tr>
</thead>
<tbody>
{
this.state.users.map((user) => (
<tr>
<td>{user.fullName}</td>
<td>{user.dob}</td>
<td>{user.gender}</td>
<td>{user.loan.map((loan) => { return (loan.id + ",") })}</td>
</tr>
))
}
</tbody>
</table>
</div>
);
}
Related
I am facing a weird problem while working with tankStack react-table. I want render some specific tags with extra data. example: i want to render the age column like this (this is the {age})
But don't want to make the tag child of tag but that is happening
Here is my code
<table>
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => {
return(
<td key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</td>
)
})
}
</tr>
))}
</tbody>
</table>
Column.js
export const COLUMNS = [
{
header:'First Name',
accessorKey:'first_name',
id:'first_name'
},
{
header:'Last Name',
accessorKey:'last_name',
id:'last_name'
},
{
header:'Age',
accessorKey:'age',
id:'age',
cell: data => <td>this is age{data.getValue()}</td>,
enableGlobalFilter: false,
}
]
i have a json file:
[ {
"symbol" : "SPY",
"type" : "etf"
}, {
"symbol" : "CMCSA",
"type" : "stock"
}, {
"symbol" : "KMI",
"type" : "stock"
}, {
"symbol" : "INTC",
"type" : "stock"
}, {
"symbol" : "MU",
"type" : "stock"
},
...
And I'm trying to read it into the table:
const Home = () =>{
const displayStockCodes = (info) =>{
JsonData.map(
(info)=>{
return(
<tr>
<td>{info.symbol}</td>
<td>{info.type}</td>
</tr>
)
}
);
};
return (
<div>
<table class="table table-striped">
<thead>
<tr>
<th>Symbol</th>
<th>Type</th>
</tr>
</thead>
<tbody>
{displayStockCodes}
</tbody>
</table>
</div>
);
};
export default Home;
I tried to do it according to the guide, but in the end only Symbol and Type are displayed on the page, and the data itself is not output. Maybe I need to add something else?
displayStockCodes is a function but you are not calling it in the tbody you need to call that function.
displayStockCodes also doesn't return anything you need to ensure it returns some JSX code.
const Home = () =>{
const displayStockCodes = (info) =>{
// 2. you need to return
return JsonData.map(
(info)=>{
return(
<tr>
<td>{info.symbol}</td>
<td>{info.type}</td>
</tr>
)
}
);
};
return (
<div>
<table className="table table-striped"> <!-- use className here instead of class -->
<thead>
<tr>
<th>Symbol</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<!-- you need to call this -->
{displayStockCodes()}
</tbody>
</table>
</div>
);
};
export default Home;
const Home = () => {
const JsonData = [
{
symbol: 'SPY',
type: 'etf',
},
{
symbol: 'CMCSA',
type: 'stock',
},
{
symbol: 'KMI',
type: 'stock',
},
{
symbol: 'INTC',
type: 'stock',
},
{
symbol: 'MU',
type: 'stock',
},
];
const displayStockCodes = () => {
return JsonData.map((info) => (
<tr>
<td>{info.symbol}</td>
<td>{info.type}</td>
</tr>
));
};
return (
<div>
<table class="table table-striped">
<thead>
<tr>
<th>Symbol</th>
<th>Type</th>
</tr>
</thead>
<tbody>{displayStockCodes()}</tbody>
</table>
</div>
);
};
export default Home;
The output:
My table.js file below. I've managed to search and filter through my table in order to display search results for show by name, but not sure how to implement a second condition so that the same search bar can be used to display searches for shows by genre.
Genres is an array, like so: genres: ["Drama", "Action", "Adventure"]
As I said previously, I'm able to filter through shows using the user input to find shows by name, but I'd like to use that same filter function to also display results by genre. Any help would be hugely appreciated.
export default class Table extends Component {
constructor(props) {
super(props);
this.state = {
searchByTitle: ""
};
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({searchByTitle : event.target.value})
}
renderRow(show) {
return (
<tr key={show.id}>
<td className="border border-green-600">
{show.image && (
<img className="w-full" src={show.image.medium} alt={show.name} />
)}
</td>
<td className="border border-green-600 bg-green-100">{show.name}</td>
<td className="border border-green-600 bg-green-100">
{show.genres.join(", ")}
</td>
<td className="border border-green-600 bg-green-100">{show.runtime}</td>
<td className="border border-green-600 bg-green-100">
{show.network && show.network.name}
</td>
<td className="border border-green-600 bg-green-100">{show.status}</td>
</tr>
);
}
render() {
const filterShows = (shows, query) => {
if (!query) {
return shows;
}
return shows.filter((show) => {
const showName = show.name.toLowerCase();
// const showGenres = show.genres.join(", ")
return showName.includes(query)
})
}
const filteredShows = filterShows(this.props.shows, this.state.searchByTitle)
return (
<table className="table-fixed border-collapse">
<thead>
<tr>
<input
type="text"
id="header-search"
placeholder="Search shows"
name="search"
onChange={this.handleChange}
/>
</tr>
<tr>
<th className="w-1/12">Poster</th>
<th className="w-4/12">Name</th>
<th className="w-4/12">Genres</th>
<th className="w-1/12">Runtime</th>
<th className="w-1/12">Network</th>
<th className="w-1/12">Status</th>
</tr>
</thead>
<tbody>{filteredShows.map((show) => this.renderRow(show))}</tbody>
</table>
);
}
}
Nevermind, I got it! Thank you to anyone who tried to help.
Just had change up my filterShows function so that it joined the array and then used toLowerCase(). See below:
const filterShows = (shows, query) => {
if (!query) {
return shows;
}
return shows.filter((show) => {
const showName = show.name.toLowerCase();
const showGenres = show.genres.join(", ").toLowerCase();
// const showGenre = show.genres;
return showName.includes(query) || showGenres.includes(query);
});
};
When I log the values from snap parameter it is displaying the values there but the rows created by renderTable function aren't rendered in a browser.
function Employees() {
const rootRef = firebase
.database()
.ref()
.child("Employees");
const renderTable = () => {
var i = 0;
return rootRef.on("value", snap => {
snap.forEach(keys => {
i++;
return (
<tr key={keys}>
...
</tr>
);
});
});
};
return (
<div className={styles.Employee}>
<h1 className={styles.header}>Employees</h1>
<table>
<thead>
<tr>
...
</tr>
</thead>
<tbody>{renderTable()}</tbody>
</table>
</div>
);
}
export default Employees;
Seems like firebase's on() method invokes callback asynchronously. You must change your approach and use state and lifecycle in your React component, ie. with some help of hooks useEffect and useState as well as map method instead of forEach. In example:
function Employees() {
const [employees, setEmployees] = useState([]);
useEffect(() => {
firebase
.database()
.ref()
.child("Employees")
.on("value", setEmployees);
}, []);
const renderTable = () => {
return employees.map((employee, i) => {
return (
<tr key={keys}>
...
</tr>
);
});
};
return (
<div className={styles.Employee}>
<h1 className={styles.header}>Employees</h1>
<table>
<thead>
<tr>
...
</tr>
</thead>
<tbody>{renderTable()}</tbody>
</table>
</div>
);
}
export default Employees;
This the where rootRef is refering to
So I updated this and it kinda works.When I log The Emp attribute in JSX it contains an array of Table rows which is how it is suppose to be. When I do this it is Rendering the last node of array. and when i use .map function on it to render all of the array it shows this error TypeError: Emps.map is not a function.
How else am i suppose to render this array?
function Employees() {
const rootRef = firebase.database().ref().child("Employees")
var i = 0
const [Emps, setEmployees] = useState([])
useEffect(() => {
rootRef.on('value', snap => {
snap.forEach(keys => {
i++
setEmployees(
<tr>
<td>{i}</td>
<td>{keys.child("Name").val()}</td>
<td>{keys.child("employee_type").val()}</td>
<td>{keys.child("email").val()}</td>
<td>{keys.child("phoneNum").val()}</td>
<td>
<input className={styles.view} name="view" type="submit" value="View"/>
</td>
</tr>
)
})
})
}, [])
return (
<div className={styles.Employee}>
<h1 className={styles.header}>Employees</h1>
<table>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Employee Type</th>
<th scope="col">Email</th>
<th scope="col">Phone #</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{
Emps
}
</tbody>
</table>
</div>
)
}
export default Employees
I want to delete an entire row (text & button) from html table on button click. How can I do that using ReactJS instead of using simple JavaScript?
code:
var RecordsComponent = React.createClass({
render : function() {
return (
<div>
<table>
<tr>
<td>row 1</td>
<td><button onClick={deleteRow}>DELETE</button></td>
</tr>
<tr>
<td>row 2</td>
<td><button onClick={deleteRow}>DELETE</button></td>
</tr>
<tr>
<td}>row 3</td>
<td><button onClick={deleteRow}>DELETE</button></td>
</tr>
</table>
</div>
);
},
deleteRow : function() {
//how to delete row using ReactJS?
},
});
React.render(<RecordsComponent/>, document.getElementById('display'))
You should to know how to make a react components.
Below is one of example to delete items.
class RecordsComponent extends React.Component {
constructor() {
super();
this.state = {
rows: ['row 1', 'row 2', 'row 3'],
};
}
deleteRow = (index) => {
// make new rows. note: react state is immutable.
const newRows = this.state.rows.slice(0, index).concat(this.state.rows.slice(index + 1));
this.setState({
rows: newRows,
});
};
render() {
const rows = this.state.rows.map((row, index) => (
<tr key={row}>
<td>{row}</td>
<td><button onClick={() => { this.deleteRow(index); }}>DELETE</button></td>
</tr>
));
return (
<div>
<table>
{rows}
</table>
</div>
);
}
}