I'm trying to implement the "save" feature from the answer in post How to use the localStorage option for DT in R Shiny? into my table rendered with rhandsontable but it's not working. That post involves table package DT, whereas I'm using rhandsontable and need to stick with rhandsontable. By "save", I mean preserving the table with all its cumulative inputs/outputs from one session to the next, which the referred-to post does for DT table. I will need to implement the "clear" function from that post later, but first I want to see how "save" works, and what I'm doing wrong in my below attempt, before moving on to adapting the "clear" function.
Below code has comments # add...
for functions I pulled in from the reference post.
How would I enable the save feature in this rhandsontable example?
I get the following error message: Error : Can't access reactive value 'hottable' outside of reactive consumer. Do you need to wrap inside reactive() or observer()?
Code:
# If not installed already, un-comment and run the below 3 lines to install shinyStore package:
# install.packages("devtools")
# library(devtools)
# install_github("trestletech/shinyStore")
library(rhandsontable)
library(shiny)
library(shinyStore)
myDF <- data.frame(x = c(1, 2, 3))
ui <- fluidPage(
initStore("store", "shinyStore-ex1"), # add
br(),
fluidRow(
column(6,
actionButton('addCol','Add column'),
actionButton("save", "Save", icon("save")), # add
actionButton("clear", "Clear", icon("stop")) # add
)
),
br(),rHandsontableOutput('hottable')
)
server <- function(input, output, session) {
EmptyTbl <- reactiveVal(myDF)
rv <- reactiveValues(uiTable = hot_to_r(input$hottable)) # add
observeEvent(input$hottable, {
EmptyTbl(hot_to_r(input$hottable))
})
output$hottable <- renderRHandsontable({
rhandsontable(EmptyTbl(),useTypes = FALSE)
})
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))
})
# add observeEvent() below:
observeEvent(input$save,{
updateStore(session,name = "uiTable",rv$uiTable)
},ignoreInit = TRUE)
}
shinyApp(ui, server)
Please check the following:
# If not installed already, un-comment and run the below 3 lines to install shinyStore package:
# install.packages("devtools")
# library(devtools)
# install_github("trestletech/shinyStore")
library(rhandsontable)
library(shiny)
library(shinyStore)
myDF <- data.frame(x = c(1, 2, 3))
ui <- fluidPage(
initStore("store", "shinyStore-ex1"),
br(),
fluidRow(column(
6,
actionButton('addCol', 'Add column'),
actionButton("save", "Save", icon("save")),
actionButton("clear", "Clear", icon("stop")) # add
)),
br(),
rHandsontableOutput('hottable')
)
server <- function(input, output, session) {
uiTable <- reactiveVal(myDF)
output$hottable <- renderRHandsontable({
rhandsontable(uiTable(), useTypes = FALSE)
})
observeEvent(input$hottable, {
uiTable(hot_to_r(input$hottable))
})
observeEvent(input$addCol, {
newCol <- data.frame(c(1, 2, 3))
names(newCol) <-
paste("Col", ncol(hot_to_r(input$hottable)) + 1)
uiTable(cbind(uiTable(), newCol))
})
observeEvent(input$save, {
updateStore(session, name = "uiTable", uiTable())
}, ignoreInit = TRUE)
observeEvent(input$clear, {
# clear tracking table:
uiTable(myDF)
# clear shinyStore:
updateStore(session, name = "uiTable", myDF)
}, ignoreInit = TRUE)
observeEvent(input$store$uiTable, {
uiTable(as.data.frame(input$store$uiTable))
})
}
shinyApp(ui, server)
PS: As an alternative approach we could use rhandsontable::set_data()
in the same manner as DT::replaceData
to avoid recreating the widget via renderRHandsontable
if the underlying table was changed.