bsky
bsky

Reputation: 20222

React - table created incorrectly

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:

enter image description here

Upvotes: 1

Views: 97

Answers (2)

Vladimir Rovensky
Vladimir Rovensky

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

gcedo
gcedo

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

Related Questions