I am trying to create a Shiny App. In this particular app i have a set of Radio buttons where choosing one will display a set of options below as Check Boxes and Choosing another radio button will choose other set of options. Kindly find the UI and the Server Code below.
library(shiny)
library(shinydashboard)
library(shinyWidgets)
d <-
data.frame(
year = c(1995, 1995, 1995, 1996, 1996, 1996, 1997, 1997, 1997),
Product_Name = c(
"Table",
"Chair",
"Bed",
"Table",
"Chair",
"Bed",
"Table",
"Chair",
"Bed"
),
Product_desc = c("X", "X", "X", "Y", "Y", "Y", "Z", "Z", "Z"),
Cost = c(1, 2, 3, 4, 2, 3, 4, 5, 6)
)
ui <- shinyUI(fluidPage(
useShinydashboard(),
tabPanel(
"Plot",
sidebarLayout(
sidebarPanel(
radioButtons(
"Choose",
"Choose One",
c("Year" = "p", "Numbers" = "l")
),
uiOutput('checkbox'),
#width = 2,
position = "bottom"),
mainPanel(uiOutput("graph"))
)
)
))
server <- function(input, output, session) {
output$graph <- renderUI({
# create tabPanel with datatable in it
req(input$year)
tabPanel("Plots",
fluidRow(lapply(as.list(paste0("plot", seq_along(input$year))), plotOutput)))
})
output$checkbox <- renderUI({
if (input$Choose == "p") {
checkboxGroupInput("Cross",
"Year",
choices = (unique(d$year)))
} else{
checkboxGroupInput("Cross_1",
"Numbers",
choices = c("1","2","3"))
}
})
}
shinyApp(ui, server)
Now the challenge which I am facing is when i choose the "Year" Radio button the year values get displayed as check boxes and when i select the check boxes a corresponding graphs get displayed in the main panel (I have not given the code over here). Now when I choose the "Number" Radio Button the correct check box options are getting displayed. But when I move back to the "Year" Radio button. The already selected check box values are not retained so the user needs to check the boxes again to get the corresponding graphs.
The choices in CheckboxGroupInput() are dynamic in my case. So i will not be able to give this choices in UI(). Also i tried using updateCheckboxGroupInput() which failed. By doing some investigations in to the code once again, I understood that the place where the issue is taking place is this part of the code.
output$checkbox <- renderUI({
if (input$Choose == "p") {
checkboxGroupInput("Cross",
"Year",
choices = (unique(d$year)))
} else{
checkboxGroupInput("Cross_1",
"Numbers",
choices = c("1","2","3"))
}
})
Please suggest me on how to retain the values in the checkbox even when the another radio button is chosen. Also please be informed that the options of Check boxes under each radio button will change according to the options the user has selected in the previous tab. So i use observe function to obtain the corresponding check boxes.
You could store the values of the years you attempt to keep in reactive values.
global <- reactiveValues(years = NULL)
observeEvent(input$Cross, {
global$years <- input$Cross
})
Then you make your dynamic ui dependent on the reactive values:
checkboxGroupInput(
"Cross",
"Year",
choices = (unique(d$year)),
selected = global$years
)
Reproducible example:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
d <-
data.frame(
year = c(1995, 1995, 1995, 1996, 1996, 1996, 1997, 1997, 1997),
Product_Name = c(
"Table",
"Chair",
"Bed",
"Table",
"Chair",
"Bed",
"Table",
"Chair",
"Bed"
),
Product_desc = c("X", "X", "X", "Y", "Y", "Y", "Z", "Z", "Z"),
Cost = c(1, 2, 3, 4, 2, 3, 4, 5, 6)
)
ui <- shinyUI(fluidPage(
useShinydashboard(),
tabPanel(
"Plot",
sidebarLayout(
sidebarPanel(
radioButtons(
"Choose",
"Choose One",
c("Year" = "p", "Numbers" = "l")
),
uiOutput('checkbox'),
#width = 2,
position = "bottom"),
mainPanel(uiOutput("graph"))
)
)
))
server <- function(input, output, session) {
global <- reactiveValues(years = NULL)
observeEvent(input$Cross, {
global$years <- input$Cross
})
output$graph <- renderUI({
# create tabPanel with datatable in it
req(input$year)
tabPanel("Plots",
fluidRow(lapply(as.list(paste0("plot", seq_along(input$year))), plotOutput)))
})
output$checkbox <- renderUI({
if (input$Choose == "p") {
checkboxGroupInput("Cross",
"Year",
choices = (unique(d$year)),selected = global$years)
} else{
checkboxGroupInput("Cross_1",
"Numbers",
choices = c("1","2","3"))
}
})
}
shinyApp(ui, server)
I think the shinyjs hide/show variant of Ash is also interesting. I havent tested it but i assume you could just replace the static ui with a dynamic there (?).
I'd suggest showing/hiding the checkboxs rather than using renderUI
. This way they will retain their settings even when they are not shown.
shinyjs
is a popular package that can do this for us. I've created a minimal example based on the above code to show this in action:
library(shiny)
library(shinyjs)
ui <- shinyUI(fluidPage(
useShinyjs(),
radioButtons("radio_choose", "Choose One", choices = c("Year", "Numbers")),
checkboxGroupInput("checkbox_years", "Year", choices = c(1995, 1996, 1997, 1997)),
checkboxGroupInput("checkbox_numbers", "Numbers", choices = c(1, 2, 3))
))
server <- function(input, output, session) {
#Observe the radio buttons (runs when the radio button changes)
observeEvent(input$radio_choose, {
if(input$radio_choose == "Year") {
shinyjs::show("checkbox_years")
shinyjs::hide("checkbox_numbers")
}
if(input$radio_choose == "Numbers") {
shinyjs::hide("checkbox_years")
shinyjs::show("checkbox_numbers")
}
})
}
shinyApp(ui, server)
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