rshinyrhandsontabledynamic-ui

Dynamic UI - Creating observeEvents for Dynamically Created Tables


Trying to understand how to create observeEvent()'s to catch changes to an arbitrary number of dynamically-created RHandsontables. Has anyone successfully done this before?

The code below shows creation of the dynamic tables. The comments towards the bottom indicate the inputs I would like to track, but the observeEvents need to account for an arbitrary set of input names.

library(shiny)
library(dplyr)
library(rhandsontable)
library(purrr)
ui <- fluidPage(

  uiOutput('tables')
)

server <- function(input, output) {
  mtcars$slc <- sample(c('aaa','bbb'),nrow(mtcars),replace=TRUE)
  df <- mtcars
  
  getSlice <- function(df_tmp,slca){
    print(slca)
    df_tmp <- df_tmp %>% filter(slc==slca)
    df_tmp
  }
  
  output$tables <- renderUI({
    slices <- unique(df$slc)
    input_dfs <- map(slices,~getSlice(df,.x))
    
    for(i in 1:length(slices)){
      local({
        i <- i
        print(input_dfs[[i]])
        output[[slices[i]]] <- renderRHandsontable(rhandsontable(input_dfs[[i]]))
      })
    }
    
    out <- map(slices,function(x){
      rHandsontableOutput(x)
    })
    print(out)
    out
  })
  
  ### How do I create observeEvents for...
  # input$aaa$changes$changes
  # input$bbb$changes$changes
  # input$arbitrarySlice$changes$changes
  
}

shinyApp(ui = ui, server = server)

Solution

  • You can iteratively add observeEvents using lapply() as shown:

    library(shiny)
    library(dplyr)
    library(rhandsontable)
    library(purrr)
    ui <- fluidPage(
        uiOutput("tables")
    )
    
    server <- function(input, output) {
        mtcars$slc <- sample(c("aaa", "bbb"), nrow(mtcars), replace = TRUE)
        df <- mtcars
    
        getSlice <- function(df_tmp, slca) {
            print(slca)
            df_tmp <- df_tmp %>% filter(slc == slca)
            df_tmp
        }
    
        output$tables <- renderUI({
            slices <- unique(df$slc)
            input_dfs <- map(slices, ~ getSlice(df, .x))
    
            for (i in 1:length(slices)) {
                local({
                    i <- i
                    print(input_dfs[[i]])
                    output[[slices[i]]] <- renderRHandsontable(rhandsontable(input_dfs[[i]]))
                })
            }
            out <- map(slices, function(x) {
                rHandsontableOutput(x)
            })
            print(out)
            out
        })
    
        ### How do I create observeEvents for...
        # input$aaa$changes$changes
        # input$bbb$changes$changes
        # input$arbitrarySlice$changes$changes
    
        ### Iteratively add observeEvent()
        lapply(unique(df$slc), function(slice) {
            observeEvent(input[[slice]]$changes$changes, {
                print(paste(slice, "has been updated!"))
                print(input[[slice]][["changes"]])
            })
        })
    
    }
    
    shinyApp(ui = ui, server = server)