reactable icon indicating copy to clipboard operation
reactable copied to clipboard

Execute JS after init

Open fabiangehring opened this issue 3 years ago • 1 comments

Hi, I'd like to have a datePicker in my table. When using DT I could do something like below. With reactable I am missing the initComplete, preDrawCallback and drawCallback. Is there a reactable-way of including datePickers in a table?

Minimal example from here

library(shiny)
library(DT)

ui <- fluidPage(

  # define a hidden dateInput in order that Shiny loads the dependencies
  div(style = "display: none;",
    dateInput("x", label = NULL)
  ),

  DTOutput("table")
)


js <- c(
  "function(settings){",
  "  $('#calendar').bsDatepicker({",
  "    format: 'yyyy-mm-dd',",
  "    todayHighlight: true",
  "  });",
  "}"
) # available options: https://bootstrap-datepicker.readthedocs.io/en/latest/


server <- function(input, output, session){

  output[["table"]] <- renderDT({
    dat <- data.frame(
      V1 = "A",
      V2 = 99, 
      V3 = '<input id="calendar" type="text" class="form-control" value = "2019-03-08"/>',
      stringsAsFactors = FALSE
    )
    datatable(dat, escape = FALSE,
              options = 
                list(
                  initComplete = JS(js),
                  preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
                  drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
                )
    )
  })

}


shinyApp(ui, server)

fabiangehring avatar Jan 16 '23 15:01 fabiangehring

Hi, I don't have any guidance on including date pickers specifically, but there are ways to get custom JavaScript-based widgets into tables. It's still in need of better documentation, but here are some quick tips for now:

  • If you create an htmlwidgets widget for the date picker library (or use an existing one if it exists), then all the initialization and rendering should happen automatically when rendered in reactable. This is a heavier-weight solution though, so not always feasible.
  • initComplete: I think an equivalent for this would be the htmlwidgets::onRender() and htmlwidgets::onStaticRenderComplete() functions that htmlwidgets provides, which works for all HTML widgets. There are some examples on how to use these in the Reactable.onStateChange() docs.
  • preDrawCallback/drawCallback: Previously, the only good way to do this would have been to write a custom React component, but there's now a Reactable.onStateChange() method in the JavaScript API that you could use to do something in the table when its state changes. For example, initialize widgets in the table when the page changes.
  • As an alternative to creating an HTML widget in R, you could also write a custom React component that wraps your widget, and all the initialization/rendering will be taken care of automatically. This is the most powerful/customizable but probably also most difficult path, and detailed documentation for this would be way out of scope. But I've started to add basic info and examples to docs that may help, starting with the Custom Filter Inputs documentation that includes a few examples of custom React-based filter inputs. There's also an older example of doing this for embedded Tweet widgets at https://github.com/glin/reactable/issues/55.

glin avatar Jan 29 '23 21:01 glin