Conditionally format entire rows in Inputs.Table

Hi there,

I am an R user that is learning Observable. I would like to have a table with some entire rows formatted (e.g., with a background color) based on the values of a single cell. I could not find or did not understand how to set any existing property of the Table widget to fill an entire row with a background color (something similar to formatStyle() in R DT).

I tried changing the values in the array of objects by injecting some HTML, but it did not work. The html code is not rendered. Any help would be very appreciated.

This is the code I used (dataframe penguins)

function changeValueinHtml(value){
  const val = htl.html`<div style='background: #fde9d2; float: left; width: 100%; display: block;'>${value}</div>`
  return val
}

function createNewArray(arToFormat){
  let newArray = [];
    arToFormat.map((val)=>{
      if (val['culmen_length_mm']>40){
        const valNew = {"species": changeValueinHtml(val["species"]),
                     "culmen_length_mm": changeValueinHtml(val["culmen_length_mm"])}
              newArray.push(valNew) 
      } else {
          const valNew = {"species": htl.html`<div>${val["species"]}</div>`,
                     "culmen_length_mm": htl.html`<div>${val["culmen_length_mm"]}</div>`}
              newArray.push(valNew) 
      }
  })
  return newArray
}

penguisFormatted = createNewArray(penguins)

Inputs.table(penguisFormatted, {})
1 Like

Inputs.table accepts a format option, as most Inputs do. Here’s an example that gets pretty close to what you want:

td_format = (d, i, data) =>
  data[i].culmen_length_mm > 40
    ? htl.html`<div style="background-color: lightblue;">${d}</div>`
    : htl.html`<div style="background-color: white;">${d}</div>`

Note that the arguments are

  • d: The current value (like 42.1 for culmen_length_mm),
  • i: the index of the data, and
  • data: the entire array of data.

Using this format function, you can format all the items in a row as follows:

Inputs.table(penguins, {
  format: {
    culmen_length_mm: td_format,
    culmen_depth_mm: td_format,
    species: td_format,
    island: td_format,
    flipper_length_mm: td_format,
    body_mass_g: td_format,
    sex: td_format
  }
})

There’s probably a shorter way to specify all the columns rather than doing explicitly for each like that. :confused:

Unfortunately, that doesn’t get the whole row, just the individual data cells. It still looks pretty close, though:

1 Like

Thank you so much.

Here’s a wrapper around Inputs.table that lets you do that:

Wow, this is awesome. Thank you so much.