How do I dynamically generate table rows without jquery? - javascript

Currently, I have a table class as follows:
import React from "react";
import "./Table.css";
export default function Table({theadData, tbodyData}) {
return (
<>
<table>
<tr>
<th></th>
<th>2017</th>
</tr>
{Array.from(theadData).forEach(heading => {
<tr>
<td class="largeHeader" key={heading}>{heading}</td>
<td class="primaryCell">{tbodyData[heading].value}</td>
</tr>;
})}
</table>
</>
);
}
When I add console.log(heading) or console.log(tbodyData[heading].value) within the loop, I can see that they give the expected values. However, none of the rows are added on. Why is that and how can I solve this problem? (I'd prefer to avoid jquery and libraries of that nature if possible, but am open to ideas.)

There are several mistakes you made:
change forEach to map
replace {} with (), or add return before <tr>
put key on the root element which is <tr>
{Array.from(theadData).map(heading => (
<tr key={heading}>
<td className="largeHeader">{heading}</td>
<td className="primaryCell">{tbodyData[heading].value}</td>
</tr>
))}

Related

Read more and read less for paragraph in react

I want to add read-more and read-less functions to a paragraph using class
I am rendering components like this
<table border="1">
<tbody>
{data
? Object.keys(data).map((item) => {
return (
<tr key={"tr" + item}>
{data[item]
? Object.keys(data[item]).map((key) => {
return (
<td
key={"td" + key}
className={key === "description" && "read-more"}
>
{data[item][key]}
</td>
);
})
: null}
</tr>
);
})
: null}
</tbody>
</table>
And the output is this
<table border="1">
<tbody>
<tr>
<td>New expense</td>
<td>default</td>
<td>10000</td>
<td class="read-more">
Long paragraph..
</td>
</tr>
<tr>
<td>New New exp</td>
<td>default</td>
<td>123</td>
<td class="read-more">
Long paragraph.. not displaying due to stack overflow too much code thing
</td>
</tr>
</tbody>
</table>
So I am making many paragraphs using objects and this runs in other components too
So all I want is a function in which it for each or use any loop to get elements class named read-more and add function to it in which it creates an anchor tag for read-more and read-less by only using a class to p tag
Please solve my problem. Thanks

React.js- Dynamic table with rowspan

I am trying to create a dynamic table, using this example- Dynamic & Complex rowspan in HTML table
I am trying to replicate the similar thing in react.js
I have put a closing tr tag in conditional rendering if the index is 0.
However, it gives me ' Expected corresponding JSX closing tag for <>'
The state 'data' object which I got from back-end is something like -
{
"100": [
"ABC"
],
"101": [
"123",
"DEF",
"XYZ",
"456",
"657",
"1234",
"4564",
"vdfgx",
"vcegefgg",
"g544"
]
}
I have written following code in component to create dynamic table.
<table>
<thead>
<tr>
<th>Code</th>
<th>Reason</th>
</tr>
</thead>
<tbody>
{Object.keys(this.state.data).map(
(error_code, i) => {
return (
<React.Fragment>
<tr>
<td
rowSpan={
this.state.data[
error_code
].length
}
key={i}
>
{error_code}
</td>
{this.state.data[
error_code
].map((error_description, index) => (
<React.Fragment>
{index === 0 ? (
<React.Fragment>
<td
key={index}
rowSpan="1"
>
{error_description}
</td>
</tr> //<--- HERE
</React.Fragment>
) : (
<tr>
<td
key={index}
rowSpan="1"
>
{error_description}
</td>
</tr>
)}
</React.Fragment>
))}
</React.Fragment>
);
}
)}
</tbody>
</table>
I want the final output something like -
<tbody>
<tr>
<td rowspan="1">100</td>
<td rowspan="1">ABC</td>
</tr>
<tr>
<td rowspan="10">101</td>
<td rowspan="1">123</td>
</tr>
<tr>
<td rowspan="1">DEF</td>
</tr>
<tr>
<td rowspan="1">XYZ</td>
</tr>
<tr>
<td rowspan="1">456</td>
</tr>
.....
</tbody>
Could anyone please guide me the correct way to achieve the desired output ?
JSX, like XML, requires proper nesting <><tr>...</tr></> and does not support overlapping tags like <><tr></></tr>. You need to structure your code in a way to preserve proper nesting:
<tbody>
{Object.keys(this.state.data).map((error_code, i) => {
return this.state.data[error_code].map((error_description, index) =>
index === 0 ? (
<tr>
<td rowSpan={this.state.data[error_code].length} key={i}>
{error_code}
</td>
<td key={index} rowSpan="1">
{error_description}
</td>
</tr>
) : (
<tr>
<td key={index} rowSpan="1">
{error_description}
</td>
</tr>
)
)
})}
</tbody>
JSX does not generate a string. It generates a tree-like structure built out of function calls and Objects. Any <tag></tag> translates into a function call, that's why your code is invalid.
You need to rethink this component.
Split the data processing and decision making into a separate function that does only that and returns the final data to be rendered. Then loop/map through it in render and return the elements structure.

Trying to get data of the row clicked of the table react js

I am new to react,and making app where I want to get data of the row being clicked on a table,I don't whether this approach is good or not need suggestions
So far i have used onClick listener but when I click on a table , it gives me [object,object] in console.log(contract),I have also tried to to use loop to view data in it but it gives me [object,object],here's my below code:
<table id="mytable" cellSpacing="0" width="100%">
<thead>
<tr>
<th>CarName</th>
<th>DriverName</th>
<th>Date</th>
<th>Pickup</th>
</tr>
</thead>
<tbody>
{
this.state.contracts.map((contract,index)=>{
return(
<tr key={index} data-item={contract} onClick={this.contractdetails}>
<td>{contract.car} </td>
<td>{contract.driver}</td>
<td>{contract.date}</td>
<td>{contract.pickup}</td>
</tr>
)})
}
</tbody>
</table>
onClickfunction
contractdetails=(e)=>{
const contract=e.currentTarget.getAttribute('data-item');
console.log(contract)
};
Use JSON.stringify while setting the data-item
<tr key={index} data-item={JSON.stringify(contract)} onClick={this.contractdetails}>
And use JSON.parse() while accessing it.
contractdetails=(e)=>{
const contract= JSON.parse(e.currentTarget.getAttribute('data-item'));
console.log(contract)
};
A better way is to just set index as data-index and you can access it from the state
this.state.contracts.map((contract,index)=>{
return(
<tr key={index} data-index={index} onClick={this.contractdetails}>
...
...
}
You can access it like below
contractdetails=(e)=>{
let index = +e.currentTarget.getAttribute('data-index')
console.log(this.state.contracts[index]);
};

Map through an array that creates a horizontal table

I am trying to map through an array and dynamically create a horizontal table, much like the image below here.
I am mapping through an array like so,
const glanceGames = this.state.gameData.map(game => {
return <GameTable
key={game.id}
home_team_name={game.home_name_abbrev}
away_team_name={game.away_name_abbrev}
home_score={game.linescore.r.home}
away_score={game.linescore.r.away}
status={game.status.status}
/>
})
and then using that data to populate the following component.
const GameTable = (props) => {
return (
<div>
<table>
<thead>
<tr>
<th>{props.status}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{props.home_team_name}</td>
<td>{props.home_score}</td>
</tr>
<tr>
<td>{props.away_team_name}</td>
<td>{props.away_score}</td>
</tr>
</tbody>
</table>
</div>
)
}
However, the output is a vertical table rather than a horizontal one. I feel like this should be easy, yet I keep running into issues. Anu suggestions would be helpful! I am using React.
I don't think this is nothing to do with react, we can just do it with css:
...
render(){
<div style={{display: 'flex'}}>
{glanceGames}
</div>
}

How do I parse an HTML file in React Native?

How can I get an HTML file from file system and parse specific elements from it.
For example, given the html snippet below, how can I extract the table content and render it?
<html>
<div>
<h1>header</h1>
<table id="a" border="1">
<th>Number</th>
<th>content A</th>
<th>contetn A</th>
<th>content A</th>
<tr>
<td>1</td>
<td>a</td>
<td>a</td>
<td>a</td>
</tr>
<th>Number</th>
<th>content B</th>
<th>content B</th>
<th>content B</th>
<tr>
<td>1</td>
<td>b</td>
<td>b</td>
<td>b</td>
</tr>
</table>
</div>
<br>
<footer>footer</footer>
</html>
Get html with fetch() and parse with react-native-html-parser, process and display with WebView.
import DOMParser from 'react-native-html-parser';
fetch('http://www.google.com').then((response) => {
const html = response.text();
const parser = new DOMParser.DOMParser();
const parsed = parser.parseFromString(html, 'text/html');
parsed.getElementsByAttribute('class', 'b');
});
P.S. fast-html-parser from other answers didn't work for me. I got multiple errors while installing it with react-native 0.54.
Just download HTML with fetch(), parse it using fast-html-parser, write result to state and render that state with WebView
I would recommend using this library: react-native-htmlviewer. It takes html and renders it as native views. You can also customize the way elements get rendered.
// only render the <table> nodes in your html
function renderNode(node, index, siblings, parent, defaultRenderer) {
if (node.name !== 'table'){
return (
<View key={index}>
{defaultRenderer(node.children, parent)}
</View>
)l
}
}
// your html
const htmlContent = `<html></html>`;
class App extends React.Component {
render() {
return (
<HTMLView value={htmlContent} renderNode={renderNode} />
);
}
}
I recommend this package react-native-render-html, is so famous and very simple for using

Categories