I am using the rhandsontable
package in a Shiny app which should have the following functionality:
actionButton
(and when the app starts)The following app does exactly that what I want, but I could not figure it out how to get rid of the global variable did_recalc
. It is a minimal example, where the data consists of two numeric values which are summed up.
library(shiny)
library(rhandsontable)
did_recalc <- FALSE
ui <- fluidPage(
rHandsontableOutput('table'),
textOutput('result'),
actionButton("recalc", "generate new random vals and calculate")
)
server <- function(input,output,session)({
dataset_generator <- eventReactive(input$recalc, {
df <- as.data.frame(runif(2))
output$table <- renderRHandsontable({rhandsontable(df)})
did_recalc <<- TRUE
df
}, ignoreNULL = FALSE)
output$result <- renderText({
df <- dataset_generator()
if (!is.null(input$table) && !did_recalc)
df <- hot_to_r(input$table)
did_recalc <<- FALSE
sum(df)
})
})
shinyApp(ui = ui, server = server)
If I remove the !did_recalc
condition within output$result <- ...
then editing the table still invokes a (correct) calculation. But if "recalc" is pressed (after some manual editing was done), then the "recalc" button just generates new random values, but without recalculating the sum.
It seems to me, that input$table
can just be changed by manual edits of the table object and does not care about new values given via renderRHandsontable
. Hence I need this hack with the global variable, which allows me to track if the user just re-generated the data (causing that input$table
is "outdated")
Has anybody an idea how to get the functionality of this example without the global variable?
If you use Handsontable through modules: to use an option that comes from a Handsontable plugin, import and register that plugin when initializing your Handsontable instance. In the example below, the cells option sets each cell in the first and fourth row as readOnly. Options modified through cells overwrite all other options.
When Handsontable is running, you can change the initial cell options, using the setCellMeta () method. You can apply configuration options to individual grid elements (columns, rows, cells), based on any logic you implement, using the cells option.
To apply configuration options to an individual column (or a range of columns), use the columns option. Within Handsontable constructor 's second argument, add an option called columns. Set the columns option to an array of objects.
Action triggered by Handsontable after the loadData or updateSettings ( {data: myData}) with the data property method has been called. Action triggered by Handsontable after requesting for populating data. Action triggered by Handsontable after the column data splicing has been done.
You could store the data in a reactiveValues
and have two observers updating it; one if the button is clicked, one if the table is edited by hand.
In your output$table
and output$result
, you then just need to use the data that is in the reactiveValues
. Here's an example (same ui.R
as you posted):
server <- function(input,output,session)({
values <- reactiveValues(data=as.data.frame(runif(2)))
observe({
input$recalc
values$data <- as.data.frame(runif(2))
})
observe({
if(!is.null(input$table))
values$data <- hot_to_r(input$table)
})
output$table <- renderRHandsontable({
rhandsontable(values$data)
})
output$result <- renderText({
sum(values$data)
})
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With