How to create a Table from lists using ReactJS? - javascript

My objective is to create the following html table from a list of rows ([1, 2, 3]) and a list of columns ([1, 2]) using ReactJS:
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
</tr>
</table>
See below for my React script and here for my codepen, which doesnt seem to be working
class Tbody extends React.Component {
constructor(props) {
super(props);
this.state = {
columns: [1, 2],
rows: [1, 2, 3]
};
}
renderCols() {
return (
{this.state.columns.map(col => <td key={col}> {col} </td>)}
);
}
renderRows(){
return (
{this.state.rows.map(row => <tr key={row}> {this.renderCols()} </tr>)}
);
}
render() {
return <tbody>{this.renderRows()}</tbody>;
}
}
class Table extends React.Component {
render() {
return (
<div>
<table>
<Tbody />
</table>
</div>
);
}
}
ReactDOM.render(<Table />, document.getElementById("root"));

Your renderCols and renderRows method returning the JSX. Instead return from there just plain JS objects, remove those {..}.
class Tbody extends React.Component {
constructor(props) {
super(props);
this.state = {
cols: [1, 2],
rows: [1, 2, 3]
};
}
renderCols() {
return (
this.state.cols.map(col => <td key={col}>{col}</td>)
);
};
renderRows(){
return (
this.state.rows.map(row => <tr key={row}>{this.renderCols()}</tr>)
);
}
render() {
return <tbody>{this.renderRows()}</tbody>;
}
}
class Table extends React.Component {
render() {
return (
<div>
<table>
<Tbody />
</table>
</div>
);
}
}
ReactDOM.render(<Table />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Related

Select all checkbox of table on click of the another table checkbox using react

I have checkboxes for each td in a table. Now, I have another table which has one checkbox. On checking this, I want to select all other checkboxes of first table.
Here is the code,
<tr key={key}>
<td align="center"> <input type="checkbox" name="myTextEditBox" value="checked" /></td>
<td>{item.technology}</td>
</tr>
for second table I did,
handleCheckBox = () => {
console.log("callling the handle change");
this.setState({
isCheckd: !this.state.isCheckd
})
}
constructure(props) {
this.state = { isCheckd: false }
<td className="text-right mr-1"><input type="checkbox" checked={this.state.isCheckd} onChange={this.handleCheckBox} /></td>
}
Now, In this click handler works. But, now how do I select all other checkboxes of another table, without using jquery.
Can any one help me with this ?
Tried solution -
state = { dynamicProp: {}, isCheckd: false,}
handleCheckBox = () => {
this.setState({
isCheckd: !this.state.isCheckd
}, () => {
this.props.jobs.forEach((item) =>
this.setState(prevState => ({
dynamicProp: {
...prevState.dynamicProp,
[item.jdName]: prevState.isCheckd
}
})
))
});
}
handleTableCheckboxChange = (e) => {
const target = e.target.name;
const checked = e.target.checked;
this.setState(prevState => ({
dynamicProp: {
...prevState.dynamicProp,
[target]: checked
}
}), () => {
const result = this.allTrue(this.state.dynamicProp);
this.setState({
isCheckd: result ? false : true
})
})
}
allTrue(obj) {
for (var o in obj)
if (!obj[o]) return true;
return false;
}
and then passing all the props to the child element. Now, the problem I am facing now is in the handleTableCheckboxChange method where I am not getting the way you used filter to get the unchecked element. and then the select all check will get changed.
I did not understand your code well so I understand it from what you have written. And then I have created a working example for you. Hope it can help you!
UPDATED CODE
const Table=(props)=>(
<table>
{
props.items.map((item, i) => (
<tr key={i}>
<td>
<input type="checkbox" checked={props.parentState[item.name]} name={item.name} onChange={props.handleChange} />
</td>
<td>{item.value}</td>
</tr>
))
}
</table>
);
class App extends React.Component {
items = [
{
value: 'EN',
name: 'field1'
},
{
value: 'IT',
name: 'field2',
}
];
state = {
checkAll: false,
};
render() {
return (
<div>
Check All
<input type="checkbox" onChange={this.handleCheckAll} checked={this.state.checkAll}/>
<Table
handleChange={this.handleChange}
items={this.items}
parentState={this.state}
/>
</div>
);
}
handleCheckAll = () => {
this.setState({
checkAll: !this.state.checkAll
}, () => {
this.items.forEach((item) => this.setState({ [item.name]: this.state.checkAll}))
});
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.checked
}, () => {
const uncheckedItems = this.items.filter((item) => !this.state[item.name])
this.setState({
checkAll: uncheckedItems.length === 0?true:false
});
});
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Here's a sample code. Obviously i haven't covered all the fail cases. Still you will get an idea about how that can be done.
import React from 'react';
export default class CheckboxIndex extends React.Component{
constructor(props){
super(props);
this.state = {
isChecked : false,
allTDS : [
{name:"name 1",value:false},
{name:"name 2",value:false},
{name:"name 3",value:false},
{name:"name 4",value:false},
{name:"name 5",value:false},
{name:"name 6",value:false},
{name:"name 7",value:false}
]
}
}
handleCheckBox = () => {
this.setState({isChecked: !this.state.isChecked});
let tempTDS = this.state.allTDS;
for (let i =0; i < tempTDS.length; i++){
tempTDS[i].value = !this.state.isChecked;
}
this.setState({allTDS : tempTDS});
};
render(){
let listOfTR;
if(this.state.allTDS.length){
listOfTR = this.state.allTDS.map((item,index)=>{
return(
<tr key={item.name}>
<td>
<label htmlFor={item.name}>
<input id={item.name} checked={item.value} type="checkbox"
onChange={()=>{
let tempObj = this.state.allTDS;
tempObj[index].value = !tempObj[index].value;
this.setState({allTDS:tempObj});
}}/>{item.name}
</label>
</td>
</tr>
)
})
}
return(
<div>
<label htmlFor="allTDS">
<input type="checkbox" id="allTDS" name="all" checked={this.state.isChecked}
onChange={this.handleCheckBox}/> All
</label>
<table>
<tbody>
{listOfTR}
</tbody>
</table>
</div>
)
}
}
class CheckboxTest extends React.Component {
constructor() {
super();
this.state = {
selectAll: false,
data1: false,
data2: false
};
this.selectAll = this.selectAll.bind(this);
this.selectField = this.selectField.bind(this);
}
selectAll() {
this.setState({
data1: !this.state.selectAll,
data2: !this.state.selectAll,
selectAll: !this.state.selectAll
});
}
selectField(event) {
if (event.target.value === "data1")
this.setState({ data1: !this.state.data1 });
else this.setState({ data2: !this.state.data2 });
}
render() {
return (
<div className="App">
<table>
<tbody>
<tr>
<td align="center">
<input
checked={this.state.data1}
onChange={this.selectField}
type="checkbox"
name="myTextEditBox1"
value="data1"
/>
</td>
<td>data 1</td>
</tr>
<tr>
<td align="center">
<input
checked={this.state.data2}
onChange={this.selectField}
type="checkbox"
name="myTextEditBox2"
value="data2"
/>
</td>
<td>data 2</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td align="center">
<input
onChange={this.selectAll}
type="checkbox"
name="myTextEditBox1"
value="all"
/>
</td>
<td>Click all</td>
</tr>
</tbody>
</table>
</div>
);
}
}
You can use the state for implementing this. Maintain state for each checkbox field and when the checkbox is changed trigger a method to set the state according to your conditions
this.setState({
isCheckd: !this.state.isCheckd
})
In this case, the isCheckd value in state corresponds to one checkbox. To select all other checkboxes of another table you have to update the values set in setState to all the values that correspond to all the boxes you want checked.
So if you have another 3 checkboxes who's values correspond to isCheckd1, isCheckd2, and isCheckd3 in state then your handler would be:
this.setState({
isCheckd1: true,
isCheckd2: true,
isCheckd3: true
})
Try this approach. you can select both the individual and check all checkbox.
class App extends React.Component {
items = ['EN', 'IT', 'FR', 'GR', 'RU'];
state = {
checkAll: false,
items : [
{'label': 'EN', 'checked': false},
{'label': 'IN', 'checked': false},
{'label': 'FR', 'checked': false},
]
};
render() {
return (
<div>
Check All
<input type="checkbox" onChange={this.handleCheckAll} />
<table>
{
this.state.items.map((item, i) => (
<tr key={i}>
<td>
<input type="checkbox" checked={item.checked} />
</td>
<td>{item.label}</td>
</tr>
))
}
</table>
</div>
);
}
handleCheckAll = () => {
let checkAll = !this.state.checkAll;
let items = this.state.items;
items.map((item, i) => {
item.checked = checkAll;
});
this.setState({
checkAll,
items
});
}
}

Sorting alphabetically a-z and z-a by using dropdown

I working on a react app where I am displaying movies data. I want to
sort data based on Title from a-z and z-a by selecting from dropdown.
Check the below code. Unable to sort correctly with this approach. As I see
there is problem in onSorting
App.js -
class App extends Component {
constructor(props) {
super(props)
this.state = {
sort_term: '', movies: data.movies
}
this.onSorting = this.onSorting.bind(this);
}
onSorting(e) {
let term = e.target.value;
const sortedList = this.state.movies.sort((a, b) => {
if (a[term] > b[term]) return 1;
if (b[term] > a[term]) return -1;
return 0;
});
this.setState({ sort_term: term });
this.setState({ movies: sortedList });
}
render() {
const { movies } = this.state;
return (
<div className="App">
<Header sort_term={this.state.sort_term}
onSorting={this.onSorting} />
{movies.length === 0 ?
<h1>Loading Movies</h1> :
<Table movies={this.state.movies} />}
</div>
);
}
}
Header.js - here is the dropdown box with two options
class Header extends Component {
render() {
const { sort_term, onSorting } = this.props;
return (
<div className="nav">
<ul className="navLeft">
<li >
<form >
<select value={sort_term}
onChange={onSorting}
className="searchBar">
<option value="Title"> Sort (A - Z)</option>
<option value="Title"> Sort (Z - A) </option>
</select>
</form>
</li>
</ul>
</div>
);
}
}
Table.js -
class Table extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
const list = this.props.movies.map((movie) => (
<tr key={movie.Title}>
<td>{movie.Title}</td>
<td>{movie.Director}</td>
</tr>
)
);
return (
<div className="table">
<table>
<thead>
<tr>
<th>Title</th>
<th>Director</th>
</tr>
</thead>
<tbody>
{list}
</tbody>
</table>
</div>
);
}
}
Actually, your code is working but since you sort A-Z you don't see the difference probably. Just change the sort function's related part like that:
if (a[term] > b[term]) return -1;
if (b[term] > a[term]) return 1;
Edit: If you have a non-sorted array your code should work. I tried it with a sorted list this is why I told you to change the order.
const movies = [
{ Title: "poo", Director: "poo" },
{ Title: "foo", Director: "bar" },
{ Title: "zoo", Director: "moo" },
]
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
sort_term: '', movies,
}
this.onSorting = this.onSorting.bind(this);
}
onSorting(e) {
let term = e.target.value;
const sortedList = [...this.state.movies].sort((a, b) => {
return a[term].localeCompare(b[term]);
});
this.setState({ sort_term: term });
this.setState({ movies: sortedList });
}
render() {
const { movies } = this.state;
return (
<div className="App">
<Header sort_term={this.state.sort_term}
onSorting={this.onSorting} />
{movies.length === 0 ?
<h1>Loading Movies</h1> :
<Table movies={this.state.movies} />}
</div>
);
}
}
class Header extends React.Component {
render() {
const { sort_term, onSorting } = this.props;
return (
<div className="nav">
<ul className="navLeft">
<li >
<form >
<select value={sort_term}
onChange={onSorting}
className="searchBar">
<option value="Title"> Sort (A - Z)</option>
<option value="Title"> Sort (Z - A) </option>
</select>
</form>
</li>
</ul>
</div>
);
}
}
class Table extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
const list = this.props.movies.map((movie) => (
<tr key={movie.Title}>
<td>{movie.Title}</td>
<td>{movie.Director}</td>
</tr>
)
);
return (
<div className="table">
<table>
<thead>
<tr>
<th>Title</th>
<th>Director</th>
</tr>
</thead>
<tbody>
{list}
</tbody>
</table>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
But, you don't have a sort direction logic in your code. You are using the same sort function and it does a one-way sort right now.
Also, do not use the state directly like that since you are mutating it. Use concat or something like that:
const sortedList = [...this.state.movies].sort((a, b) => {
if (a[term] > b[term]) return -1;
if (b[term] > a[term]) return 1;
return 0;
});
Even better, you can use localCompare to make the sort more reliable. Thanks to #msbit for the comment and pointing out that.
const sortedList = [...this.state.movies].sort((a, b) => {
return a[term].localeCompare(b[term]);
});

how to call a function from another component in react

I am appending a text box on click of Add New Candidate button and I also want to call validate the function of NewCandidate component on the click of save button I have tried with the following code but it's throwing an error if anybody knows the solution please answer.........................................................................................................................................
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0-alpha1/JSXTransformer.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.9.0/firebase.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/jsx">
class NewCandidate extends React.Component{
validate(){
alert()
}
render(){
return(
<table>
<tr>
<th colSpan="2">Candidate details</th>
</tr>
<tr>
<th>Name</th><td><input type="text" ref="candName" /></td>
</tr>
</table>
)
}
}
var CandidateList = [<NewCandidate />];
class Interview extends React.Component{
constructor(props){
super();
this.state={candidates:props.candidates}
}
updateCandidateList(newCandidate){
var updatedCandidates=this.state.candidates;
updatedCandidates.push(newCandidate);
this.setState({candidates: updatedCandidates})
}
render(){
return(
<div>
<Candidate candidates={this.state.candidates} />
<AddNewCandidate candidateList={this.updateCandidateList.bind(this)} />
</div>
)
}
}
class AddNewCandidate extends React.Component{
constructor(){
super()
}
addNewCandidate(e){
e.preventDefault();
this.props.candidateList(<NewCandidate />)
}
render(){
return(
<form>
<button onClick={this.addNewCandidate.bind(this)}>Add New Candidate</button>
<button type="button" onClick={NewCandidate.validate.bind(this)}>Save</button>
</form>
)
}
}
class Candidate extends React.Component{
constructor(props){
super(props);
}
render(){
var items=this.props.candidates.map((item)=>{
return (<div>{item}</div>)
});
return(
<div>
{items}
</div>
)
}
}
ReactDOM.render(<Interview candidates={CandidateList}/>,document.getElementById("root"));
</script>
</body>
</html>
Please check the following working snippet.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="https://unpkg.com/react#15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom#15/dist/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.9.0/firebase.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class NewCandidate extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e){
e.preventDefault();
this.props.handleCandidateChange(e.target.value, this.props.indexVal);
}
render(){
return(
<div>
<table>
<tbody>
<tr>
<th colSpan="2">Candidate details</th>
</tr>
<tr>
<th>Name</th><td><input type="text" onChange={this.handleChange}/></td>
</tr>
</tbody>
</table>
</div>
)
}
}
class Interview extends React.Component {
constructor(props){
super(props);
this.state = {
candidates: [],
values: []
}
this.addNewCandidate = this.addNewCandidate.bind(this);
this.handleSave = this.handleSave.bind(this);
this.handleCandidateChange = this.handleCandidateChange.bind(this);
}
handleCandidateChange(value, index) {
const newValues = [].concat(this.state.values);
newValues[index] = value;
this.setState({values: newValues});
}
handleSave(e) {
e.preventDefault();
this.state.values.forEach((val, index) => {
alert(`Validate ${index+1} value`);
})
}
addNewCandidate(e) {
e.preventDefault();
const candidateList = [].concat(this.state.candidates);
candidateList.push(<div key={`candidate-${candidateList.length}`}><NewCandidate indexVal={candidateList.length} handleCandidateChange={this.handleCandidateChange}/></div>)
this.setState({candidates: candidateList});
}
render() {
return (
<div>
{this.state.candidates}
<button type="button" onClick={this.addNewCandidate}>Add New Candidate</button>
<button type="button" onClick={this.handleSave}>Save</button>
</div>
)
}
}
// render Interview component
ReactDOM.render(<Interview />,document.getElementById("root"));
</script>
</body>
</html>
Here's an example. The main App component acts as a container for all relevant information and actions. We then use child components that are used for presenting data which will be using methods that have been passed down from the container to perform actions.
class NewCandidate extends React.Component {
state = {
name: ""
};
handleChange = evt => this.setState({
name: evt.target.value
});
addCandidate = () => {
const { name } = this.state;
if (name === "") {
return console.warn("input is empty");
}
return this.setState({
name: '',
}, () => this.props.add(name));
};
render() {
if (this.props.display) {
return (
<div>
<label>Name</label>
<input
type="text"
value={this.state.name}
onChange={this.handleChange}
/>
<button onClick={this.addCandidate}>Add Candidate</button>
</div>
);
}
return null;
}
}
const Candidate = ({ candidate }) => <div>{candidate.name}</div>;
class App extends React.Component {
state = {
showNewCandidateForm: false,
candidates: [
{
id: 1,
name: "Jeff"
},
{
id: 2,
name: "Andrew"
},
{
id: 3,
name: "Jess"
}
]
};
addCandidate = name => {
alert('validation here');
const { candidates } = this.state;
this.setState({
showNewCandidateForm: false,
candidates: [
...candidates,
{
id: candidates[candidates.length - 1].id + 1,
name,
}
]
});
};
showNewCandidateForm = () => this.setState({
showNewCandidateForm: true
});
hideNewCandidateForm = () => this.setState({
showNewCandidateForm: false
});
render() {
return (
<div>
<NewCandidate
display={this.state.showNewCandidateForm}
hide={this.hideNewCandidateForm}
add={this.addCandidate}
/>
{this.state.candidates.map(candidate => {
return <Candidate key={candidate.id} candidate={candidate} />;
})}
<button onClick={this.showNewCandidateForm}>New Candidate</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

React : How to manage state for multiple input types

Working on a POC that displays tennis player details in a page.There can be 'n' number of players displayed. The user can update information of all the players at the same time.
Written 3 components PlayersPage, PlayerTable and PlayerRow. I am little confused on how to update the state(playerData) in PlayersPage when the player information is updated in PlayerRow. Any pointer/link will be helpful.
Below is the code:
class PlayersPage extends React.Component {
constructor(props) {
super(props);
this.state = {
playerData: [
{
"dataKey": "300",
"playerFirstName": "Roger",
"playerLastName": "Federer",
"playerRanking": "1"
},
{
"dataKey": "301",
"playerFirstName": "Rafael",
"playerLastName": "Nadal"
"playerRanking": "2"
}
]
};
}
render() {
return (
<div className="container">
<PlayerTable tableData={this.state.playerData} />;
</div>
);
}
}
class PlayerTable extends React.Component {
render() {
const rows = [];
this.props.tableData.forEach((rowData) => {
rows.push(<PlayerRow key={rowData.dataKey} rowData={rowData} />);
});
return (
<div className="table-responsive">
<table className="table table-condensed">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Ranking</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
</div>
);
}
}
PlayerTable.propTypes = {
tableData: PropTypes.array.isRequired
};
class PlayerRow extends React.Component {
render() {
return (
<tr>
<td><input type="text" value={this.props.rowData.playerFirstName} /></td>
<td><input type="text" value={this.props.rowData.playerLastName} /></td>
<td><input type="text" value={this.props.rowData.playerRanking} /></td>
</tr>
);
}
}
PlayerRow.propTypes = {
rowData: PropTypes.object.isRequired
};
class PlayersPage extends React.Component {
constructor(props) {
super(props);
this.changeRecord = this.changeRecord.bind(this);
this.state = {
playerData: [
{
"dataKey": "300",
"playerFirstName": "Roger",
"playerLastName": "Federer",
"playerRanking": "1"
},
{
"dataKey": "301",
"playerFirstName": "Rafael",
"playerLastName": "Nadal",
"playerRanking": "2"
}
]
};
}
changeRecord(record, event) {
console.log(event.currentTarget.value);
console.log(record);
this.setState({
// Write your logic to update the playerDate value accordingly
});
}
render() {
return (
<div className="container">
<PlayerTable recordChangeHandler={this.changeRecord} tableData={this.state.playerData} />;
</div>
);
}
}
class PlayerTable extends React.Component {
render() {
const rows = [];
this.props.tableData.forEach((rowData) => {
rows.push(<PlayerRow recordChangeHandler={this.props.recordChangeHandler} key={rowData.dataKey} rowData={rowData} />);
});
return (
<div className="table-responsive">
<table className="table table-condensed">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Ranking</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
</div>
);
}
}
class PlayerRow extends React.Component {
render() {
return (
<tr>
<td><input type="text" onChange={this.props.recordChangeHandler.bind(this, this.props.rowData)} defaultValue={this.props.rowData.playerFirstName} /></td>
<td><input type="text" onChange={this.props.recordChangeHandler} defaultValue={this.props.rowData.playerLastName} /></td>
<td><input type="text" onChange={this.props.recordChangeHandler} defaultValue={this.props.rowData.playerRanking} /></td>
</tr>
);
}
}
ReactDOM.render(
<PlayersPage />,
document.getElementById('container')
);
Checkout the JSFiddle example you can probably emulate in your POC app.
https://jsfiddle.net/69z2wepo/86736/
Component communication can be achieved by passing data via props.
Check out this link, specifically section 3.
How do you send data from a child to its parent?
The simplest way is for the parent to pass a function to the child. The child can use that function to communicate with its parent.
The parent would pass a function to the child as a prop, like this:
<MyChild myFunc={this.handleChildFunc.bind(this)} />
And the child would call that function like so:
this.props.myFunc();
And don't forget that the child will need this function declared in its propTypes:
MyChild.propTypes = {
myFunc: React.PropTypes.func,
};

React.js - Creating simple table

Sorry for what it appears to be a newbie question (been up working late and just got started with React) but I am trying to figure out how to just render a simple table with nxn dimension.
For instance, in my component, the render output would be something like this:
<table id="simple-board">
<tbody>
<tr id="row0">
<td id="cell0-0"></td>
<td id="cell0-1"></td>
<td id="cell0-2"></td>
</tr>
<tr id="row1">
<td id="cell1-0"></td>
<td id="cell1-1"></td>
<td id="cell1-2"></td>
</tr>
<tr id="row2">
<td id="cell2-0"></td>
<td id="cell2-1"></td>
<td id="cell2-2"></td>
</tr>
</tbody>
</table>
where each row has it's own id , as well as each cell.
The initial state
constructor(props){
super(props);
this.state = {size: 3}
}
is what set the size of the table.
What threw me of was how to implement a for loop inside the JSX.
After a good night sleep, I was able to figure it out:
import React, { Component } from 'react'
export default class Example extends Component {
constructor(props){
super(props);
this.state = {size: 3}
}
render(){
let rows = [];
for (var i = 0; i < this.state.size; i++){
let rowID = `row${i}`
let cell = []
for (var idx = 0; idx < this.state.size; idx++){
let cellID = `cell${i}-${idx}`
cell.push(<td key={cellID} id={cellID}></td>)
}
rows.push(<tr key={i} id={rowID}>{cell}</tr>)
}
return(
<div className="container">
<div className="row">
<div className="col s12 board">
<table id="simple-board">
<tbody>
{rows}
</tbody>
</table>
</div>
</div>
</div>
)
}
}
Thanks all for responding!
One option (move stuff out of render():
import React from 'react';
import SimpleListMenu from '../menu/SimpleMenuListMenu'; // < Material UI element
let rows = [
'Setting One',
'Setting Two',
'Setting Three',
'Setting Four',
];
export default class MyTable extends React.Component {
createTable = () => {
let table = []
for (let i = 0; i < rows.length; i++) {
let children = []
children.push(<td>{rows[i]}</td>, <td>{<SimpleListMenu />}</td>)
table.push(<tr>{children}</tr>)
}
return table
}
render() {
return(
<table>
{this.createTable()}
</table>
)
}
}
Another option:
import React from 'react';
let id = 0;
function createData(option, type) {
id += 1;
return { id, option, type };
}
let rows = [
createData('Setting One', 'Private'),
createData('Setting Two', 'Public'),
createData('Setting Three', 'Group'),
createData('Setting Four', 'Private'),
];
export default class MyTable extends React.Component {
render() {
return(
<table>
{rows.map(row => (
<tr key={row.id}>
<td>{row.option}</td>
<td>{row.type}</td>
</tr>
))}
</table>
)
}
}
See: https://material-ui.com/demos/tables/
somthing like this :
<table id="simple-board">
<tbody>
{this.props.yourData.slice(0,this.state.size).map((item , index)=>{
return(
<tr key={index} id={`row${index}`}>
{item.felanBisar.map((item2,index2)=>{
return(
<td id={`cell${index}-{index2}`}></td>
);
})}
</tr>
);
})}
</tbody>
</table>
private getRows(): any {
let rows: any[] = [];
if (this.state.data)
this.state.data.map((element) => {
rows.push(<tr>
<td style={{border: '1px solid black'}}>
{element.title}
</td>
</tr>);
});
return rows;
}
render( ) {
return <div>
<table style={{border: '1px solid black'}}>
{this.getRows()}
</table>
</div>
}
Building the table from an array with a function, and rows with alternate bgColor:
function buildTable(arr){
const rows = arr.map((row,i) => {
return <tr style={{backgroundColor: i%2 ? '#F0FFF2':'white'}} key={i}>
<td>{row[0]}</td><td>{row[1]}</td>
</tr>
})
return <table><tbody>{rows}</tbody></table>
}
const data = [["FieldA", "aaa"],["FieldB", "bbb"],["FieldC", "ccc"]];
buildTable(data);

Categories