Search code examples
rrenderingshinyaction-button

Shiny - actionButton: rendering without clicking


In the simple example below, a graphic is rendered function of inputs from a checkboxGroupInput after refreshing with the button. At the first start of the app, the selected checkbox is provided by the selectInput s1.

# ui.R
library(shiny)
shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("s1", "Select 1", 1:5)
    ),
      mainPanel(
        plotOutput("myplot"),
        uiOutput("chk.output"),
        actionButton("refresh", "Refresh")
      )
    )
  )
)
# server.R
library(shiny)
shinyServer(function(input, output, session) { 
  output$chk.output <- renderUI(checkboxGroupInput("Chk", label = "Choices", choices = list("1" = 1, "2" = 2, "3"= 3, "4"=4, "5"=5), selected = input$s1, inline = TRUE, width = "100%"))
  selectGrEv <- eventReactive(input$refresh, {input$Chk}, ignoreNULL = FALSE)
  output$myplot <- renderPlot({ 
    plot(1:5, 1:5)
    if (1 %in% selectGrEv()) {text(1,1, labels= 1, col = "red", pos = 3)}
    if (2 %in% selectGrEv()) {text(2,2, labels= 2, col = "blue", pos = 3)}
    if (3 %in% selectGrEv()) {text(3,3, labels= 3, col = "black", pos = 3)}
    if (4 %in% selectGrEv()) {text(4,4, labels= 4, col = "orange", pos = 3)}
    if (5 %in% selectGrEv()) {text(5,5, labels= 5, col = "green", pos = 1)}
  })
})

When the user changes input$s1, the checkboxGroupInput is refreshed but not the plot what is normal. I would like to refresh the plot eihter by clicking on the Refresh button or by changing input$s1.

I tried to modify server.R by adding a counter with reactiveValues:

# server.R
library(shiny)
shinyServer(function(input, output, session) { 
  output$chk.output <- renderUI(checkboxGroupInput("Chk", label = "Choices", choices = list("1" = 1, "2" = 2, "3"= 3, "4"=4, "5"=5), selected = input$s1, inline = TRUE, width = "100%"))

  values <- reactiveValues(cpt = 0) # Here code was added
  observeEvent(input$s1, values$cpt <- values$cpt + 1) # Here code was added

  selectGrEv <- eventReactive(input$refresh | values$cpt, {input$Chk}, ignoreNULL = FALSE) # Here code was modified
  output$myplot <- renderPlot({ 
    plot(1:5, 1:5)
    if (1 %in% selectGrEv()) {text(1,1, labels= 1, col = "red", pos = 3)}
    if (2 %in% selectGrEv()) {text(2,2, labels= 2, col = "blue", pos = 3)}
    if (3 %in% selectGrEv()) {text(3,3, labels= 3, col = "black", pos = 3)}
    if (4 %in% selectGrEv()) {text(4,4, labels= 4, col = "orange", pos = 3)}
    if (5 %in% selectGrEv()) {text(5,5, labels= 5, col = "green", pos = 1)}
  })
})

the value values$cpt changes when input$s1 changes but not selectGrEv() thus the plot is not refreshed.

How can I get a refresh of the rendered plot when the user changes input$s1 as well ?


Solution

  • I know only one( may be no good variant)

    Try

    ##Server.r
    shinyServer(function(input, output, session) { 
      output$chk.output <- renderUI(checkboxGroupInput("Chk", label = "Choices", choices = list("1" = 1, "2" = 2, "3"= 3, "4"=4, "5"=5), selected = input$s1, inline = TRUE, width = "100%"))
      selectGrEv <- reactiveValues(aa=0)
    
      observeEvent(input$s1,{
        selectGrEv$aa=input$s1
        })
    
      observeEvent(input$refresh,{
        selectGrEv$aa=input$Chk
      })
    
      output$myplot <- renderPlot({ 
    
        plot(1:5, 1:5)
        if (1 %in%  selectGrEv$aa) {text(1,1, labels= 1, col = "red", pos = 3)}
        if (2 %in% selectGrEv$aa) {text(2,2, labels= 2, col = "blue", pos = 3)}
        if (3 %in% selectGrEv$aa) {text(3,3, labels= 3, col = "black", pos = 3)}
        if (4 %in% selectGrEv$aa) {text(4,4, labels= 4, col = "orange", pos = 3)}
        if (5 %in% selectGrEv$aa) {text(5,5, labels= 5, col = "green", pos = 1)}
      })
    })