0

I am wrestling with adding columns via action button to a data frame rendered via the rhandsontable package (for later formatting reasons I need to use an action button for adding columns instead of relying on rhandsontable's contextMenu). The below code almost works but I get strange results every 2nd click of the "Add" action button. Probably due to my not completely understanding how the click counter works, in the line ...if(input$addCol > 0){testDF}.... Anyhow, every click of "Add" should add a column to the rendered table (default values of 1, 2, 3), and the user must be able to manually overwrite the default values with those revised values retained through further Add clicks. The images below explain better, and the code is at the bottom.

How can I fix the below code so it works as intended? Where a click of "Add" adds a column, and manual changes to the table are retained?

enter image description here

enter image description here

Code:

library(shiny)
library(rhandsontable)

myDF <- data.frame(x = c(1,2,3))

ui <- fluidPage(
  rHandsontableOutput('hottable'),br(),
  actionButton('addCol','Add')
)

server <- function(input, output, session) {
  
  observe({myDFOut <<- print(hot_to_r(input$hottable))})
  
  output$hottable <- renderRHandsontable({
    rhandsontable(if(input$addCol > 0){testDF} else {myDF})
  })

  observeEvent(input$addCol,{
    newCol <- data.frame(c(1,2,3))
    names(newCol) <- paste("Col",ncol(hot_to_r(input$hottable))+1)
    testDF <<- cbind(hot_to_r(input$hottable),newCol)
  })
  
}

shinyApp(ui, server)
Village.Idyot
  • 1,359
  • 2
  • 8

1 Answers1

2

Try using reactiveVal(about the function here).

library(shiny)
library(rhandsontable)

myDF <- data.frame(x = c(1, 2, 3))

ui <- fluidPage(rHandsontableOutput('hottable'),
                br(),
                actionButton('addCol', 'Add'))

server <- function(input, output, session) {
  EmptyTbl <- reactiveVal(myDF)
  
  observeEvent(input$hottable, {
    EmptyTbl(hot_to_r(input$hottable))
  })
  
  output$hottable <- renderRHandsontable({
    rhandsontable(EmptyTbl())
  })
  
  observeEvent(input$addCol, {
    newCol <- data.frame(c(1, 2, 3))
    names(newCol) <- paste("Col", ncol(hot_to_r(input$hottable)) + 1)
    EmptyTbl(cbind(EmptyTbl(), newCol))
    
  })
  
}

shinyApp(ui, server)
ViviG
  • 1,613
  • 1
  • 9
  • 23