Reputation: 20222
I have a table in React where the user can add a variable number of rows.
<div>
<table class="table table-condensed table-bordered">
<tr>
<th>List Names</th>
<th>List Full Names</th>
<th>List Descriptions</th>
</tr>
{this.displayTableBody()}
</table>
<button style={{display:'inline-block'}} type="button"
className="btn btn-primary btn-small" onClick={this.addList}>
<span className="glyphicon glyphicon-plus"></span>
</button>
</div>
The rows are added by the displayTableBody
method:
displayTableBody: function() {
var rows = Array.apply(null, Array(this.state.rowNr)).map(
function(e1, index) {
return <ListInput key={index} ref={index}/>
}
);
return(<div>{ rows }</div>);
}
One row is made of a ListInput
component, which has the following render
method:
render: function() {
return (
<tr>
<td>{this.displaySimpleInputField(
"List Name(<15 characters - A-Z, 0-9 and _ only)", this.setListName, "input")}</td>
<td>{this.displaySimpleInputField(
"List Full Name(<75 characters)", this.setListFullName, "input")}</td>
<td>{this.displaySimpleInputField(
"List Description(<225 characters)", this.setListDescription, "input")}</td>
</tr>
)
}
However, when I add a row, it is placed above the table header:
Upvotes: 1
Views: 97
Reputation: 4704
When working with tables, it is doubly important to write valid HTML, otherwise you get weird results like this. Specifically, the correct structure of a table is kinda like this:
<table>
<thead>
<tr><th></th></tr>
</thead>
<tbody>
<tr><td></td></tr>
</tbody>
</table>
Specifically, I'm pretty sure you can't place a div
directly in table
, like you do with your displayTableBody
method. Try to rewrite your component to follow the HTML standard, I believe that's what causes your problem.
Upvotes: 2
Reputation: 4931
You are inserting div
element directly inside a table, which is not correct html and it does break the layout, placing that element at the top of the table.
I would suggest restructuring your code as follows, and consider using times
function from lodash:
displayTableBody: function() {
var rows = times(this.state.rowNr).map(
function(index) {
return <ListInput key={index} ref={index}/>
}
);
return(<tbody>{ rows }</tbody>);
}
And the table
<table class="table table-condensed table-bordered">
<thead>
<tr>
<th>List Names</th>
<th>List Full Names</th>
<th>List Descriptions</th>
</tr>
</thead>
{this.displayTableBody()}
</table>
Upvotes: 1