I want to include a checkboxgroup with one button into a datatable in R. Thanks to https://github.com/rstudio/DT/issues/93#issuecomment-111001538 I found how to use bind and unbind in shiny in order to tell shiny that I created some elements on the fly. So now shiny knows that my elements exist. However the callbacks are either not working or firing twice...
Let me give you a MWE:
library(shiny)
ui <- fluidPage(
shinyjs::useShinyjs(),
actionButton("browser", "browser"),
DT::dataTableOutput(
outputId = "dtout"
),
shinyjs::hidden(numericInput(
inputId = "computeSumOfRow",
label = NULL,
value = 0
))
)
server <- function(input, output, session) {
observeEvent(input$browser, browser())
observeEvent(input$computeSumOfRow,{
i <- input$computeSumOfRow
cat("Start computing sum for row", i, "\n")
str(i)
allNumbers <- input[[paste0("checkboxId", i)]]
allNumbers <- as.integer(allNumbers)
print(sum(allNumbers))
}, ignoreInit = TRUE)
list_of_events <- lapply(1:5, function(i){
observeEvent(input[[paste0("buttonId",i)]],{
cat("Button ", i, "pressed and triggered external event\n")
str(input[[paste0("buttonId",i)]])
})
})
output$dtout <- DT::renderDT({
checkboxes <- sapply(1:5, function(i){
as.character(div(
checkboxGroupInput(
inputId = paste0("checkboxId", i),
label = "Select the number you want to compute the sum",
choices = 1:7 + 10*i
),
actionButton(
inputId = paste0("buttonId",i),
label = "compute the sum",
onclick = sprintf("Shiny.setInputValue(id=\"computeSumOfRow\", %i, {priority: \"event\"});", i)
)
))
})
dt <- data.frame(
checkboxes = checkboxes
)
DT::datatable(
dt,
escape = FALSE,
selection = "none",
options = list(
preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
)
)
})
}
shinyApp(ui, server)
To reproduce what I got please select buttons 24, 25 and 26 and click the second button.
When you look into the console, you see that the computeSumOfRow
was triggered twice: The first time correctly (like I specified in my onclick
-event) and the second time with the number of times the button has been clicked. If you do not unbind+bind while creating the datatabe, then only the first (correct) event is triggered. However, then shiny does not of the existence of the checkboxgroups (you can see that e.g. by going into the browser and typing input$
and you do not get the autocomplete-options checkboxId1
and so on).
My custom events (the ones created using lapply
) however did not work even with the unbind+bind trick.
What should I change so that my code works as expected?