Ben
Ben

Reputation: 267

Call back reactable which included radio button by row

I am able to use DT table to create the table which contained three columns. I can call back the table to return the radio input. I am not sure how to call back in reactable. If anyone knows please share the ideas.



library(shiny)
library(DT)
library(reactable)
filter_names <- row.names(mtcars)
shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    h5("DT table"),
    DT::dataTableOutput('foo'),
    tableOutput('sel'),
    hr(),
    h5("Reactable"),
    reactableOutput("foo_reactable")
    
  ),
  server = function(input, output, session) {
    
    values <- reactiveValues()
    
    m = matrix(
      c("1","0","2"), nrow = length(filter_names), ncol = 3, byrow = TRUE,
      dimnames = list(filter_names,c("Include","Exclude","Ignore")))
    
    for (i in seq_len(nrow(m))) {
      m[i, ] = sprintf(
        '<input type="radio" name="%s" value="%s" checked="checked"/>',filter_names[i], m[i, ])}
    
    m_dat <- as.data.frame(m)
    m_dat$var <- filter_names
    
    output$foo = DT::renderDataTable(
      m_dat, escape = FALSE, selection = 'none', server = FALSE,
      options = list(dom = 't', paging = FALSE, ordering = FALSE),
      callback = JS("table.rows().every(function(i, tab, row) {
          var $this = $(this.node());
          $this.attr('id', this.data()[0]);
          $this.addClass('shiny-input-radiogroup');
        });
        Shiny.unbindAll(table.table().node());
        Shiny.bindAll(table.table().node());")
    )
    
    output$sel = renderTable({
      out <- cbind(filter_names, unlist(sapply(filter_names, function(i) {input[[i]]})))
      out

    })
    
    output$foo_reactable = renderReactable(
      reactable(m_dat,
                columns = list(
                  Include = colDef(html = TRUE),
                  Exclude = colDef(html = TRUE),
                  Ignore = colDef(html = TRUE)
                ))
    ) 
  } 
)

Upvotes: 0

Views: 75

Answers (1)

Zekiye
Zekiye

Reputation: 98

An alternative to consider is using dropdown inputs within a reactable table to set the status of each row.

enter image description here

Here is a coded example;

library(shiny)
library(reactable)
library(reactable.extras)

shinyApp(
 ui = fluidPage(
  reactable.extras::reactable_extras_dependency(),
  reactableOutput('table')
 ),
 server = function(input, output) {

  table_data <- reactiveVal(
   data.frame(
    Name = c('1', '0', '2'),
    status = c("Include", "Exclude","Ignore"),
    stringsAsFactors = FALSE,
    row.names = 1:3
   )
  )
  output$table <- renderReactable({
   reactable(
    table_data(),
    columns = list(
      status = colDef(
        header = "",
        cell = dropdown_extra(id = "status", 
                              c("Include", "Exclude", "Ignore"), 
                              class = "dropdown-extra")
      )
     )
    )
   })
   observeEvent(input$status, {
    df <- table_data()
  
    df$status[input$status$row] <- input$status$value
    print(df)
    table_data(df)
   })
  }
 )

Upvotes: 1

Related Questions