1
votes

Problem: In below Shiny app, I want to change and insert new rows to the following data via rhandsontable:

data.frame(car = c("Opel", "Nissan", "Opel", "VW"),
                 location = c("Ruesselsheim", "Frankreich", "Ruesselsheim", "Wolfsburg"))
  1. If I change for example car == Opel to car == VW the location shall change from Ruesselsheim to Wolfsburg.
  2. If I insert a new row and for example populate it with car == Opel then location shall be Ruesselsheim directly after providing the car input

Question: How can I conditionally change the cell values and define conditional default values?

Attempts: hot_col has a default argument but it only accepts a string and not a condition. Also tracking the changes via an observer seems not really the best way to do it.

Any ideas on how to approach this? Many thanks!

library(shiny)
library(rhandsontable)

ui = shinyUI(fluidPage(
  
  titlePanel("Handsontable"),
  
  sidebarLayout(
    sidebarPanel(
      rHandsontableOutput("hot")
    ),
    mainPanel(
      verbatimTextOutput("debug")
    )
  )
))

server = function(input, output) {

  
  data <- reactive({
      data.frame(car = c("Opel", "Nissan", "Opel", "VW"),
                 location = c("Ruesselsheim", "Frankreich", "Ruesselsheim", "Wolfsburg"))
    })
  
  output$hot <- renderRHandsontable({
    DF <- data()
    rhandsontable(DF, useTypes = FALSE, selectCallback = TRUE)
  })
  
  ### DEBUG
  output$debug <- renderPrint({
    req(input$hot)
  
    input$hot$changes
  })  
}

shinyApp(ui = ui, server = server)

1

1 Answers

1
votes

The desired behaviour can be achived by using a reactiveVal and a lookup-table to merge the current selection with:

library(shiny)
library(rhandsontable)

ui = shinyUI(fluidPage(
  
  titlePanel("Handsontable"),
  
  sidebarLayout(
    sidebarPanel(
      rHandsontableOutput("hot")
    ),
    mainPanel(
      verbatimTextOutput("debug")
    )
  )
))

server = function(input, output) {
  
  LUT_DF <- data.frame(car = c("Opel", "Nissan", "VW"),
                   location = c("Ruesselsheim", "Frankreich", "Wolfsburg"))
  
  data <- reactiveVal(data.frame(car = c("Opel", "Nissan", "Opel", "VW"),
                                 location = c("Ruesselsheim", "Frankreich", "Ruesselsheim", "Wolfsburg")))
  
  output$hot <- renderRHandsontable({
    rhandsontable(data(), useTypes = FALSE, selectCallback = TRUE)
  })
  
  observeEvent(input$hot, {
    data(merge(LUT_DF, hot_to_r(input$hot)[1], by = "car"))
    }, ignoreInit = TRUE)

}

shinyApp(ui = ui, server = server)

result