Ad

Dynamically Create Data Table In ReactJS

- 1 answer

I have problem with creating dynamic data table in ReactJs. In state.data I get my data which I loop to create data table.

Here is my render function:

render: function() {
        return (
            <div>
                <table id="measurementsDataTable" className="row-border compact">
                    {
                        this.state.data.map(function(item) {
                            if( item.element == "th" ){
                                return (
                                    <thead>
                                        <tr>
                                            <ThElement width="280" data={item.description}/>
                                            <ThElement width="150" data={item.L1}/>
                                        </tr>
                                    </thead>
                                )
                            }
                            else if ( item.element == "tr" ) {
                                return (
                                    <tbody>
                                        <tr>
                                            <TdElement data={item.description}/>
                                            <TdElement data={item.L1}/>
                                        </tr>
                                    </tbody>
                                )
                            }
                        })
                    }

                </table>
            </div>
        );
    }

The problem is the element "tbody" which is given to the every single "tr" row. And it should be just in first "tr" to last "tr".

This would't be a problem if I could just return start of "tbody", but react doesn't allow that.

Is there any elegant solution to that?

Edit: Currently is HTML looking like this. All the difference is in the "tbody" element.

<table>
<thead>
    <tr>
        <th>Phase</td>
        <th>L1</td>
    </tr>
</thead>
<tbody>
    <tr>
        <td>Voltage</td>
        <td>224.2</td>
    </tr>
</tbody>
<tbody>
    <tr>
        <td>Current</td>
        <td>0.00 mA</td>
    </tr>
</tbody>    
<thead>
    <tr>
        <th>Phase 2</td>
        <th>L2</td>
    </tr>
</thead>
<tbody>
    <tr>
        <td>Voltage2</td>
        <td>223.2</td>
    </tr>
</tbody>
<tbody>
    <tr>
        <td>Current2</td>
        <td>0.00 mA</td>
    </tr>
</tbody>

and It should looking like this:

<table>
<thead>
    <tr>
        <th>Phase</td>
        <th>L1</td>
    </tr>
</thead>
<tbody>
    <tr>
        <td>Voltage</td>
        <td>224.2</td>
    </tr>
    <tr>
        <td>Current</td>
        <td>0.00 mA</td>
    </tr>
</tbody>    
<thead>
    <tr>
        <th>Phase 2</td>
        <th>L2</td>
    </tr>
</thead>
<tbody>
    <tr>
        <td>Voltage2</td>
        <td>223.2</td>
    </tr>
    <tr>
        <td>Current2</td>
        <td>0.00 mA</td>
    </tr>
</tbody>

Ad

Answer

You can group your data by header with Array.prototype.reduce() and then create appropriate elements:

render: function() {

    var tableElements = this.state.data.reduce(function(grouped, item) {
        if (item.element == "th") {
            grouped.push({
                header: item,
                rows: []
            });
        } else {
            grouped[grouped.length - 1].rows.push(item);
        }
        return grouped;
    }, []).reduce(function(elements, item) {
        elements.push(<thead>
                          <tr>
                              <ThElement width="280" data={item.header.description}/>
                              <ThElement width="150" data={item.header.L1}/>
                          </tr>
                      </thead>);
        elements.push(<tbody>
                      {
                          item.rows.map(function(row) {
                              return (<tr>
                                          <TdElement data={row.description}/>
                                          <TdElement data={row.L1}/>
                                      </tr>);
                          });
                      }
                      </tbody>);
        return elements;

    }, []);

    return (
        <div>
            <table id="measurementsDataTable" className="row-border compact">
            { tableElements }
            </table>
        </div>
    );
}
Ad
source: stackoverflow.com
Ad