Banshee
Banshee

Reputation: 15807

How to turn objects in to HTML

How do i get this :

<li>
 <div class='myClass1'>myData1</div>
 <div class='myClass2'>myData2</div>
 <div class='myClass3'>myData3</div>
 <div class='myClass4'>myData4</div>
</li>

from this code

var data1 = {"Columns":[{"Title":"Title1","HTMLClass":"g1_Title"},{"Title":"Title2","HTMLClass":"g2_Title"},{"Title":"Title3","HTMLClass":"g3_Title"}],"Rows":[{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]},{"Cells":["Cell0","Cell1","Cell2"]}]};



var GridRow = React.createClass({
    render: function() {
        var data = [], columns;

        // puts all the data in to a better structure (ideally the props would have this structure or this manipulation would be done on onReceiveProps)
        if(this.props.columns){
            for(var ii = 0; ii < this.props.columns.length; ii++){
                data.push({
                    class: this.props.columns[i].HTMLClass,
                    contents: this.props.Cell[i]
                })
            }
        }

        // Its best to map JSX elements and not store them in arrays
        columns = data.map(function(col) {
            return <div className= + {col.class}> {col.contents} </div>;
        });

        return (
            <div>
                <li>
                    {columns}
                </li>
            </div>
        );
    }
});
var GridHead = React.createClass({
    render: function() {
        if(this.props.data){
            var cell = this.props.data.Title;
            var htmlClass = this.props.data.HTMLClass;
        }
        return (
            <div className={htmlClass}>{cell}</div>
        );
    }
});
var GridList = React.createClass({
    render: function() {
        if(this.props.data){
            var header = this.props.data.Columns.map(function (columns) {
                return (
                    <GridHead data={columns} />
                );
            });
            var row = this.props.data.Rows.map(function (row, i) {
                return (
                    <GridRow columns={data1.Columns} cells={row.Cells}  key={i} />
                );
            });
        }
        return (
            <ul>
                <li>{header}</li>
                {row}
            </ul>
        );
    }
});


var GridBox = React.createClass({
    render: function(){
        return (
            <GridList data={data1} />
        );
    }
});

The output right now is this

In file "~/Scripts/Grid.jsx": Parse Error: Line 26: XJS value should be either an expression or a quoted XJS text (at line 26 column 35) Line: 52 Column:3

Upvotes: 0

Views: 279

Answers (1)

DWB
DWB

Reputation: 1554

As your question initially asked was to do with just the GridRow component and nothing else I have not touched any other component.

Your main problem was you were assigning className = + //something in your GridRow component which isn't the correct way to assign. There were other errors like missing div tags.

Better GridRow

When the component mounts a columndata variable is created and is populated with formatted data using formatData();.

I do not recommend you do data formatting in this component (although it is doable). You should either format your data at a top level component and pass down formatted data or accept data in the correct structure.

My GridRow component to this:

var GridRow = React.createClass({        
  componentWillMount: function() {
      this.columndata = [];
      this.formatData();
  },

  formatData: function() {  // Formats prop data into something manageable
    if (this.props.columns && this.props.cells) {
            for(var ii = 0; ii < this.props.columns.length; ii++){
                this.columndata.push({
                    class: this.props.columns[ii].HTMLClass,
                    contents: this.props.cells[ii]
                })
            }
      this.forceUpdate();   // Forces a rerender
    }

  },

  componentDidUpdate: function(prevProps, prevState) {
      // If this component receives the props late
      if (!prevProps.cells && !prevProps.columns) {
        this.formatData();
      }
  },

  render: function() {
      var columns;

      // Its best to map JSX elements and not store them in arrays
      columns = this.columndata.map(function(col) {
          return <div className={col.class}> {col.contents} </div>;
      });

      return (
          <div>
              <li>
                  {columns}
              </li>
          </div>
      );
  }
});

I think it's important to note that you should avoid storing JSX elements in arrays.

I think you were basically on the money, except you were missing classname and div tags.

Upvotes: 1

Related Questions