glin/reactable

How to filter the rows automatically using a default group name ?

JauntyJJS opened this issue · 2 comments

Hi,

I apologise if I were to ask something very trivial.

I wanted to create a filtered reactable based on a default input of a specific filter group.
Using the iris data set as an example, this is what I wish to obtain after running the code on the console.

image

The code that I have is as follows:

iris |>
  reactable::reactable(
    showPageSizeOptions = TRUE,
    defaultPageSize = 50,
    highlight = TRUE, 
    height = 500,
    theme = reactable::reactableTheme(style = list(color = "grey")),
    defaultColDef = reactable::colDef(# for all columns
      filterable = TRUE,
      html = TRUE
    ),
    columns = list(
      Species = reactable::colDef(
        filterInput = reactable::JS("
        function(column, state) {
          // input:
          //  - column, an object containing column properties
          //  - state, an object containing the table state
          //
          // output:
          //  - element to render (e.g. an HTML string or React element)
          return React.createElement('input', {
            type: 'text',
            defaultValue: 'versicolor',
            value: column.filterValue,
            onChange: function(e) {
                return column.setFilter(e.target.value || undefined)
            },
            'aria-label': 'Filter ' + column.name,
          })
       }")
      )
    )
  )

Created on 2023-05-15 with reprex v2.0.2

The good news is that I managed to have the text "versicolor", automatically written in the textbox. However, the rows are not filtered by "versicolor" automatically. I need to click on the text box, press a space to make the filter happen.

Is there a way to create a "default state", in the code to tell the program to do the filtering ?

glin commented

Hi, I think this makes for a great case to add a default filter/search value to reactable(), like you can already do with default sorting state. Something like reactable(iris, defaultFiltered = list(Species = "versicolor")) perhaps.

In the meantime, this should be possible with the JavaScript API method to update filter values. You don't need a custom filter input to do this, but it's also not super straightforward, so here's an example. The tricky part is to use htmlwidgets::onStaticRenderComplete() to run the JavaScript filter method only after the table has been fully rendered.

library(htmltools)

tbl <- iris |>
  reactable::reactable(
    showPageSizeOptions = TRUE,
    defaultPageSize = 50,
    highlight = TRUE, 
    height = 500,
    theme = reactable::reactableTheme(style = list(color = "grey")),
    defaultColDef = reactable::colDef(# for all columns
      filterable = TRUE,
      html = TRUE
    ),
    elementId = "tbl"
  )

browsable(
  tagList(
    tbl,
    htmlwidgets::onStaticRenderComplete("
      Reactable.setFilter('tbl', 'Species', 'versicolor')
    ")
  )
)

I would add an example like this to the docs, but I think it'd be better to just add default filter options soon anyway.

@glin. Noted with thanks.
It work well for me.