Home > Enterprise >  How to change color of a table row based on object property value?
How to change color of a table row based on object property value?

Time:10-06

I have an array of objects as output from API as below:

var x = [{
    name: "test",
    group: [{
      name: "rating",
      value: "55"
    }]
  },
  {
    name: "test1",
    group: [{
      name: "rating",
      value: "20"
    }]
  },
  {
    name: "test2",
    group: [{
      name: "rating",
      value: "60"
    }]
  },
  {
    name: "test3",
    group: [{
      name: "rating",
      value: "10"
    }]
  }
]
<table>
  <tr>
    <td>test</td>
    <td>test1</td>
    <td>test2</td>
    <td>test3</td>
  </tr>
</table>

I am trying to change the color of all the rows of the table to green based on the object value x.group[0].value greater than 30. Any idea how can I achieve this? I am trying to group the arrays with the values greater than 30 but I am not sure how can I change color based on that.

for (var i = 0; i < x.length; i  ) {
  x[i].group[0].value
}

Note: I am using ReactJS. I created a Table component like this. I am not sure if I can change HTML much

CodePudding user response:

You can use a condition to determine whether or not x.group[0].value is bigger than 30

<table>
    <tr style={{backgroundColor: !!(x.group[0].value > 30) ? 'green': 'red'}}>test</tr>
    <tr style={{backgroundColor: !!(x.group[0].value > 30) ? 'green': 'red'}}>test1</tr>
    <tr style={{backgroundColor: !!(x.group[0].value > 30) ? 'green': 'red'}}>test2</tr>
    <tr style={{backgroundColor: !!(x.group[0].value > 30) ? 'green': 'red'}}>test3</tr>
</table>

Adding this line style={{ backgroundColor: !!true ? "green" : "red" }} to line 101 inside the tag in your code example makes the table rows green. Change the condition to use your value, and it'd be green/your color depending on the condition

CodePudding user response:

You can make use of clsx library with which you can provide multiple classNames conditionally.

<tr
  className={clsx({
    defaultClass: true,
    tableGreen: x.group[0].value > 30,
    // other conditional classes
  })}
>
  ...
</tr>

In your styles.css

.defaultClass {
  padding: 5px;
}

.tableGreen {
  backgroundColor: #00ff00;
}

For it to work with react-table you will have to modify the the array structure

function transform(y) {
  return y.map((i) => ({
    name: i.name,
    ...i.group.reduce((acc, curr) => ({ ...acc, [curr.name]: curr.value }), {}),
  }));
}

It will give you output like this

[
    {
        "name": "test",
        "rating": "55"
    },
    {
        "name": "test1",
        "rating": "20"
    },
    {
        "name": "test2",
        "rating": "60"
    },
    {
        "name": "test3",
        "rating": "10"
    }
]

When comparing, make sure to convert the rating into a number type using parseInt. Eventually in the Table component as in the example you provided.

<tbody {...getTableBodyProps()}>
  {page.map((row, i) => {
    prepareRow(row);
    return (
      <tr
        {...row.getRowProps()}
        className={clsx({
          defaultClass: true,
          tableGreen: parseInt(row.original.rating) > 30,
          // other conditional classes
        })}
      >
        {row.cells.map((cell) => {
          return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
        })}
      </tr>
    );
  })}
</tbody>
  • Related