1

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!

Casper
  • 33
  • 3
  • What do you mean by "another shiny page". If it is a tab inside the shiny app we can use `updateTabsetPanel()` inside `observeEvent()` see [here](https://shiny.rstudio.com/reference/shiny/0.14/updatetabsetpanel). – TimTeaFan Feb 22 '23 at 13:16
  • I'm setting up a sequential study, so I don't want users to navigate freely between tabs - I want them redirected to a separate shiny file, with a whole new ui when they press a certain action button – – Casper Feb 22 '23 at 13:54
  • There are packages which allow you to provide two different UIs. You can also do it yourself, but it is more work than just using tabs. I would use tabs and just hide them from the user, so that they cannot access them. But I'd say this part is worth a separate question. – TimTeaFan Feb 22 '23 at 14:05
  • Appreciated - didn't want to post a question yet since I'm only just learning and haven't actually run into issues yet. I'll crack on, and hopefully there'll be some good learning materials out there. Thanks! – Casper Feb 22 '23 at 14:17

1 Answers1

0

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)
TimTeaFan
  • 17,549
  • 4
  • 18
  • 39