reactable icon indicating copy to clipboard operation
reactable copied to clipboard

Implementation of reactableLang filterPlaceholder for individual columns

Open tbrittoborges opened this issue 3 years ago • 1 comments

We can now use filterMethod for complex filtering in columns. However, I could not find a away to add a placeholder to explain the different filtering methods for each column.

In short, this works as intended:

reactable(
  iris[1:30, ],
  filterable = TRUE,
  language = reactableLang(
    filterPlaceholder = "TEST"),
)

But this does not work:

reactable(
  iris[1:30, ],
  filterable = TRUE,
  columns = list(
    `Sepal.Length` = colDef(
    language = reactableLang(
      filterPlaceholder = "TEST")
    )
  )
)

Is there a way to overcome this?

tbrittoborges avatar Sep 28 '22 14:09 tbrittoborges

It's not possible to add column-specific placeholders through reactableLang(), and reactableLang() is intended more for generic messages that multiple tables could use globally. In hindsight, the filter placeholder probably makes more sense as a column-specific option since it could depend on the column for a specific table.

The only way to work around this now would be to custom render your own filter inputs, like described at Custom Filter Inputs.

For example, here's a slight modification on the basic custom filter input (React) example to add an "All" placeholder:

data <- MASS::Cars93[, c("Manufacturer", "Model", "Type", "Price")]

reactable(
  data,
  columns = list(
    Manufacturer = colDef(
      filterable = TRUE,
      filterInput = JS("function(column) {
        return React.createElement('input', {
          type: 'text',
          value: column.filterValue,
          onChange: function(event) {
            // Set to undefined to clear the filter
            return column.setFilter(event.target.value || undefined)
          },
          'aria-label': 'Filter ' + column.name,
          placeholder: 'All',
          style: { width: '100%' }
        })
      }")
    )
  ),
  defaultPageSize = 5
)

Reusing the custom filter across different columns could be done with some string templating:

filter_input <- function(placeholder = "") {
  reactable::JS(
    sprintf("function(column) {
      return React.createElement('input', {
        type: 'text',
        value: column.filterValue,
        onChange: function(event) {
          // Set to undefined to clear the filter
          return column.setFilter(event.target.value || undefined)
        },
        'aria-label': 'Filter ' + column.name,
        placeholder: '%s',
        style: { width: '100%%' }
      })
    }", placeholder)
  )
}

data <- MASS::Cars93[, c("Manufacturer", "Model", "Type", "Price")]

reactable(
  data,
  columns = list(
    Manufacturer = colDef(
      filterable = TRUE,
      filterInput = filter_input("All manufacturers")
    ),
    Model = colDef(
      filterable = TRUE,
      filterInput = filter_input("All models")
    )
  ),
  defaultPageSize = 5
)

glin avatar Oct 16 '22 22:10 glin