1

I am building a React.js application where I want to allow users to input styles in a text area which will affect the style of another element.

First, I have a row component which looks like this:

function Row(props) {
  return (
    <tr>
      <td width="50%">
        <textarea 
          style={{}} 
          value={props.style}
          onChange={props.onStyleChange}>
        </textarea>
      </td>
      <td><div className="">Row {props.id+1}</div></td>
    </tr>
  )
}; 

I am iterating through a list of rowData to populate my rows, which can be found here:

{this.state.rowData.map(function(row, index) {
  return (
    <Row 
        id={row.id} 
        style={row.style} 
        onStyleChange={function(e) {this.onStyleChange(e, row.id)}.bind(this)}/>
          );
}.bind(this))}

Then in my onStyleChange function I have:

onStyleChange: function(e, id) {
  this.state.rowData[id].style = e.target.value;
  this.setState(this.state);
}

So as a user enters data into the the textarea, it adds to the i'th element in my rowData array. Assuming its the 0th row and the user enters "Hello" into the text area, then rowData[0].style = "Hello".

However, I would like to be able to do something like this: style={{props.style}} inside my Row component. But because it is currently a string it does not work. I have also tried style={JSON.parse(props.style)} which throws an error every time I add a new row because props.style='{}'. The error reads Uncaught SyntaxError: Unexpected token f in JSON at position 1

Always grateful for any help. There's got to be a much easier way to do this. Thank you.

2 Answers 2

2

Two steps to convert inline-style toobject-style` as restricted by React :

  1. Parse the string to be a JSON object.

  2. Convert the keys of this object to camel case (z-index becomes zIndex.. so on)

Congrats! i wrote the algorithm , check below :

const example1= "position:absolute;h-index:9001;"
const example2 = "-ms-transform: rotate(20deg);-webkit-transform: rotate(20deg);";
// 2ⁿᵈ step logic
const camelize = (string) =>  string.replace(/-([a-z])/gi,(s, group) =>  group.toUpperCase());

// 1ˢᵗ step logic which calls the 2ⁿᵈ step logic
const style2object = (style) => style.split(';').filter(s => s.length)
        .reduce((a, b) => {
           const keyValue = b.split(':');
           a[camelize(keyValue[0])] = keyValue[1] ; 
           return a;
         } ,{});


console.log("Example 1 : ", example1, '\n',
  style2object(example1)
)

console.log("Example 2 : ", example2, '\n',
  style2object(example2)
)

Sign up to request clarification or add additional context in comments.

Comments

0

If it is helpful the style attribute needs an object like {"color": "blue"}

I made a demo with your code the only thing that escapes me is how to update with the onChange event.

function Row(props) {
  const styleValue = JSON.stringify(props.style);
  return (
    <tr>
      <td width="50%">
        <textarea 
          style={props.style} 
          defaultValue={styleValue}
          onChange={props.onStyleChange}/>

      </td>
      <td><div className="">Row {props.id+1}</div></td>
    </tr>
  )
};

class App extends React.Component {
  state = {
    rowData: [{
      id: 1,
      style: {
        color: 'blue'
      }
    }, {
      id: 2,
      style: {
        color: 'red',
        backgroundColor:'#000'
      }
    }]
  };

  onStyleChange(e, id) {
    const rows = this.state.rowData;
    const row = rows.find(row => row.id  === id);
    const index = rows.indexOf(row);
    rows[index]['style'] = JSON.parse(e.target.value);
    this.setState({
      rowData: rows
    });
  }
  render() {
    return (
      <table>
         <tbody>
      {
      this.state.rowData.map(function(row, index) {
        return (
          <Row 
        id={row.id} 
        key={index}
        style={row.style} 
        onStyleChange={function(e) {this.onStyleChange(e, row.id)}.bind(this)}/>
        );
      }.bind(this))

    }
          </tbody>
    </table>
    )
  }
}

ReactDOM.render(<App/>, document.getElementById('app'));

http://codepen.io/GGarciaSeco/pen/vgVEGX?editors=0010

You can take a look to the React documentation in the next link

https://facebook.github.io/react/docs/dom-elements.html#style

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.