Search code examples
rshinyshinyappsaction-button

Refreshing randomly selected action buttons in Shiny


So, I'm building an app where my input is randomly selected. It's a set of recommendations, picked at random from a list, each one embedded in an action button that will (eventually) take the user to the related activity page. I've seen plenty of tutorials on how to reactively change the output in a shiny app, but commonly to all these tutorials, the input boxes stay the same. Below is an example that illustrates what I mean. When you restart the app, the three action button icons are reselected from the list, but I'm having trouble finding a way to re-generate the options via the fourth action button (refresh) within the app.

library(shiny)

#Functions


##Multiple linebreaks
linebreaks <- function(n){
  HTML(strrep(br(), n))
}

##Imagefinder
choose_icon <- function(id,icon){
  tags$button(
    id = id,
    class = "btn action-button",
    icon(icon)
  )
}

#Icons

icon1 <- choose_icon("house", "house")
icon2 <- choose_icon("user", "user")
icon3 <- choose_icon("check", "check")
icon4 <- choose_icon("download", "download")
icon5 <- choose_icon("phone", "phone")

refresh <- choose_icon("refresh", "arrows-rotate")

##list the images for random selection
icon_list <- list(icon1,icon2,icon3,icon4,icon5)

#UI
ui <- fluidPage(
  titlePanel("Please choose one of the following recommendations:"),
  linebreaks(2),
  fluidRow(
    sample(icon_list, 3)
  ),
  linebreaks(2),
  titlePanel("Or generate new ones:"),
  linebreaks(2),
  fluidRow(
    refresh
  )
)


# Define server logic ----
server <- function(input, output, session) {
}

# Run the app ----
shinyApp(ui = ui, server = server)

I've tried a few things already within server, but nothing has shown any sign of working I've left it blank.

Also, optional bonus - anyone know any good resources or tutorials for learning how to get an action button to redirect to another shiny page?

Hope someone can help

Thanks!


Solution

  • We can use reactiveValues and resampe the icon_list when the intput$refresh button is clicked. We need however to move this part of the UI to the server:

    library(shiny)
    
    #Functions
    
    ##Multiple linebreaks
    linebreaks <- function(n){
      HTML(strrep(br(), n))
    }
    
    ##Imagefinder
    choose_icon <- function(id,icon){
      tags$button(
        id = id,
        class = "btn action-button",
        icon(icon)
      )
    }
    
    #Icons
    
    icon1 <- choose_icon("house", "house")
    icon2 <- choose_icon("user", "user")
    icon3 <- choose_icon("check", "check")
    icon4 <- choose_icon("download", "download")
    icon5 <- choose_icon("phone", "phone")
    
    refresh <- choose_icon("refresh", "arrows-rotate")
    
    ##list the images for random selection
    icon_list <- list(icon1,icon2,icon3,icon4,icon5)
    
    #UI
    ui <- fluidPage(
      titlePanel("Please choose one of the following recommendations:"),
      linebreaks(2),
      fluidRow(
        uiOutput("sample_buttons")
      ),
      linebreaks(2),
      titlePanel("Or generate new ones:"),
      linebreaks(2),
      fluidRow(
        refresh
      )
    )
    
    
    # Define server logic ----
    server <- function(input, output, session) {
      
      r <- reactiveValues(buttons = sample(icon_list, 3))
      
      observeEvent(input$refresh, {
        r$buttons <- sample(icon_list, 3)
      })
      
      output$sample_buttons <- renderUI(r$buttons)
    }
    
    # Run the app ----
    shinyApp(ui = ui, server = server)