Search code examples
shinyshiny-servershiny-reactivityrhandsontableshinyapps

Rhsiny: Automatically update an output object based on updated rhandsontable object


I have an app with two tables. One table is a renderhandsontable object and the other is just a rendertable object. I would like for when I update my renderhandsontable object for it to automatically update my rendertable object. My renderhandontable object is created by data elsewhere in the app using a number of filters.

I have referenced several very useful posts here to help me get this far in creating a reactive table that could be used in multiple output objects such as

How to render multiple output from the same analysis without executing it multiple time? (Shiny)

Get selected rows of Rhandsontable

Handsontable : how to change cell value in render function

but I cannot seem to get past this last hurdle. I also tried adding a button (using eventReactive) so the table would update when I pressed it rather than automatically, but had no luck there (and automatic would definitely be preferred).

I have created an overly simplified version of my server code below.

#dummy data
x = c('A','A','A', 'B','B', 'c')
y = c('G1', 'G1', 'G1', 'G2', 'G2','G3')
z = c('100', '200', '300', '400','500','600')

b=data.frame('Category' = x,
             'Group' = y,
             'Total' = z)

#create reactive object to be used in multiple places
test <- reactive({

  t <-filter(b, b$Category %in% input$cat & b$Group %in% input$group)

  return(t)

})

output$test_table <- renderTable({

  tbl = data.frame(matrix(0, ncol = 4, nrow = 4))

#I know something needs to be done prior to this step to get updated values #of test()

  tbl[1,1] <- test()[1,3]

  return(tbl)
})


output$contents <- renderRHandsontable({

  rhandsontable(test())

})

I can get my tables to appear properly and the data to update initially, but once I make an update to my table, it is not reflected in my second table.

I have really been struggling with this for quite some time so any help or hints would be greatly appreciated !


Solution

  • Please read this. You can access the rhandsontable params via input$my_id. To get the current data use input$my_id$params$data.

    Here is what I think you are after:

    library(shiny)
    library(rhandsontable)
    
    ui <- fluidPage(rHandsontableOutput("contents"),
                    tableOutput("test_table"),
                    tableOutput("test_table_subset"))
    
    server <- function(input, output) {
    
      # dummy data
      x = c('A', 'A', 'A', 'B', 'B', 'C')
      y = c('G1', 'G1', 'G1', 'G2', 'G2', 'G3')
      z = c('100', '200', '300', '400', '500', '600')
    
      b = data.frame('Category' = x,
                     'Group' = y,
                     'Total' = z)
    
      # create reactive object to be used in multiple places
      test <- reactive({
        t <- b # dplyr::filter(b, b$Category %in% input$cat & b$Group %in% input$group)
        return(t)
      })
    
      output$contents <- renderRHandsontable({
        rhandsontable(test())
      })
    
      contentsTableDat <- reactive({
        req(input$contents)
        hot_to_r(input$contents)
      })
    
      output$test_table <- renderTable({
        contentsTableDat()
      })
    
      output$test_table_subset <- renderTable({
        contentsTableDat()[1, 3]
      })
    }
    
    shinyApp(ui = ui, server = server)