In shiny, I have two tables displayed with rhandsontable, I have already implemented that whenever a cell value is changed the cell gets colored, however when switching between the tables all the changes disappear since naturally the table reloads everytime from the start, is it possible to somehow save the changed cell, so as long as you do not quit the session or do not press "reset" all the changes remain even if you switch between the tables?
(code based on the solution of the following thread: in shiny: rhandsontable / afterChange, change multiple cell backgrounds at once)
library(shiny)
library(rhandsontable)
library(tidyverse)
change_hook <- "function(el,x) {
hot = this.hot;
cellchngs = [];
afterChange = function(changes, source) {
$.each(changes, function (index, elem) {
change = elem; /* gather the row, col, old, new values */
if(change[2] !== change[3]) { /* if old isn't the same as new */
cellchg = ({rowind: change[0], colind: change[1]});
cellchngs.push(cellchg); /* add row and column indicies to array */
}
});
$.each(cellchngs, function(ind, elem) {
td = hot.getCell(elem['rowind'], elem['colind']); /* get the html element */
td.style.background = 'cyan'; /* set background color */
});
}
hot.addHook('afterChange', afterChange); /* add event to table */
}"
ui <- div(actionButton(inputId = "reset_button",label = "Reset"), selectInput("data", "Choose data",choices=c("mtcars"=1, "iris"=2), selected=1)
,rHandsontableOutput(outputId="mtcars"))
server <- function(input, output, session) {
reset <- reactiveVal(0)
output$mtcars <- renderRHandsontable({
r = reset()
myvec <- c("mtcars", "iris")
mydata <- eval(parse(text=myvec[as.numeric(input$data)]))
rht = rhandsontable(mydata,reset=r,stretchH="all",height=300)
reset(0)
htmlwidgets::onRender(rht,change_hook)
})
observeEvent(input$reset_button,
{
reset(1)
})
}
shinyApp(ui, server)
You can use hidden tabsetPanels to achieve that.
Note that I did not change the change_hook
block.
library(shiny)
library(rhandsontable)
change_hook <- "function(el,x) {
hot = this.hot;
cellchngs = [];
afterChange = function(changes, source) {
$.each(changes, function (index, elem) {
change = elem; /* gather the row, col, old, new values */
if(change[2] !== change[3]) { /* if old isn't the same as new */
cellchg = ({rowind: change[0], colind: change[1]});
cellchngs.push(cellchg); /* add row and column indicies to array */
}
});
$.each(cellchngs, function(ind, elem) {
td = hot.getCell(elem['rowind'], elem['colind']); /* get the html element */
td.style.background = 'cyan'; /* set background color */
});
}
hot.addHook('afterChange', afterChange); /* add event to table */
}"
ui <- fluidPage(
actionButton(inputId = "reset_button",label = "Reset"),
selectInput(
inputId = "data",
label = "Choose data",
choices = c("mtcars", "iris")
),
tabsetPanel(
id = "tabs",
type = "hidden",
tabPanelBody(
value = "mtcars",
rHandsontableOutput(outputId = "mtcars")
),
tabPanelBody(
value = "iris",
rHandsontableOutput(outputId = "iris")
)
)
)
server <- function(input, output, session) {
reset <- reactiveVal(0)
output$mtcars <- renderRHandsontable({
r = reset()
rht = rhandsontable(
mtcars,
reset = r,
stretchH = "all",
height = 300
)
reset(0)
htmlwidgets::onRender(rht, change_hook)
})
output$iris <- renderRHandsontable({
r = reset()
rht = rhandsontable(
iris,
reset = r,
stretchH = "all",
height = 300
)
reset(0)
htmlwidgets::onRender(rht, change_hook)
})
observeEvent(input$reset_button, {
reset(1)
})
# if the selectInput value changes, switch tabs:
observeEvent(input$data, {
updateTabsetPanel(
session = session,
inputId = "tabs",
selected = input$data
)
})
}
shinyApp(ui, server)