This app shows a radiobutton choice between 3 lists : lower, upper, digit items
To test it, save the following code below in a directory "shiny" and in an app.R file. Then launch R and type :
library(shiny
runApp("shiny")
Default choice is lower list.
A sentence "select or type an item" appears in the choice list, thanx to the placeholder option.
If I choose an item in this list like "a", the choosed item appears in the mainpanel on the right.
If I change the kind of list says digit, a new choice list appears with digits as choice.
BUT the first item choosed "a" disappears from the mainpanel on the right.
If I choose the digit "2" it appears in the mainpanel on the right.
The issue is that I want to keep the choosed item in the mainpanel even if I change the kind of list with the radiobutton.
I don't understand why this choice disappears because in the oberveEvent of the radiobutton the rval reactiveValues don't change.
library(shinyjs)
ui <-fluidPage(
useShinyjs(),
id = "page",
sidebarLayout(position = "left",
sidebarPanel(
radioButtons(
"choice_btn", "Choose list:",
c("Lower" = "lower", "Upper" = "upper", "Digit" = "digit"),
selected="lower"
),
selectizeInput(
inputId="lower_choice",
label="List of lower items",
choices=NULL,
selected=NULL,
options = list(placeholder='select or type an item')
),
selectizeInput(
inputId="upper_choice",
label="List of upper items",
choices=NULL,
selected=NULL,
options = list(placeholder='select or type an item')
),
selectizeInput(
inputId="digit_choice",
label="List of digit items",
choices=NULL,
selected=NULL,
options = list(placeholder='select or type an item')
)
),
mainPanel(
textOutput("item")
)
)
)
server <- function(input, output, session) {
rval <- reactiveVal()
updateSelectizeInput(session, 'lower_choice', choices = c("a","b","c","d"), selected = character(0), server = TRUE)
updateSelectizeInput(session, 'upper_choice', choices = c("A","B","C","D") , selected = character(0), server = TRUE)
updateSelectizeInput(session, 'digit_choice', choices = c(1,2,3,4) , selected = character(0), server = TRUE)
shinyjs::hide("upper_choice")
shinyjs::hide("digit_choice")
output$item <- renderText({ rval() })
observeEvent(input$choice_btn, {
choice <- input$choice_btn
choices <- c("lower", "upper", "digit")
shinyjs::show(paste0(choice,"_choice"))
updateSelectizeInput(session, 'lower_choice', choices = c("a","b","c","d"), selected = character(0), server = TRUE)
updateSelectizeInput(session, 'upper_choice', choices = c("A","B","C","D"), selected = character(0), server = TRUE)
updateSelectizeInput(session, 'digit_choice', choices = c(1,2,3,4), selected = character(0), server = TRUE)
for (x in choices) {
if ( x != choice ) {
shinyjs::hide(paste0(x,"_choice"))
}
}
})
observeEvent(input$lower_choice, {
rval(input$lower_choice)
})
observeEvent(input$upper_choice, {
rval(input$upper_choice)
})
observeEvent(input$digit_choice, {
rval(input$digit_choice)
})
# end shinyServer
}
shinyApp(ui, server)
Thanx for your help
CodePudding user response:
IMHO the issue is that all of your selectizeInput
s are updated when the user switches the type of list. And as a consequence the selected value is for each selectizeInput
is set to an empty string ""
. Accordingly the observeEvent
for the selected list is triggered and the reactiveVal
gets updated with an empty string which is what the textInput
displays.
One option to prevent that would be to add an if
statement to each of your observeEvent
s to update the reactiveVal
only when the user made a choice, i.e. when the choice is different from an empty string:
library(shinyjs)
library(shiny)
ui <- fluidPage(
useShinyjs(),
id = "page",
sidebarLayout(
position = "left",
sidebarPanel(
radioButtons(
"choice_btn", "Choose list:",
c("Lower" = "lower", "Upper" = "upper", "Digit" = "digit"),
selected = "lower"
),
selectizeInput(
inputId = "lower_choice",
label = "List of lower items",
choices = NULL,
selected = NULL,
options = list(placeholder = "select or type an item")
),
selectizeInput(
inputId = "upper_choice",
label = "List of upper items",
choices = NULL,
selected = NULL,
options = list(placeholder = "select or type an item")
),
selectizeInput(
inputId = "digit_choice",
label = "List of digit items",
choices = NULL,
selected = NULL,
options = list(placeholder = "select or type an item")
)
),
mainPanel(
textOutput("item")
)
)
)
server <- function(input, output, session) {
rval <- reactiveVal()
output$item <- renderText({
rval()
})
observeEvent(input$choice_btn, {
choice <- input$choice_btn
choices <- c("lower", "upper", "digit")
for (x in choices[!choices %in% choice]) {
shinyjs::hide(paste0(x, "_choice"))
}
shinyjs::show(paste0(choice, "_choice"))
updateSelectizeInput(session, 'lower_choice', choices = c("a","b","c","d"), selected = character(0), server = TRUE)
updateSelectizeInput(session, 'upper_choice', choices = c("A","B","C","D"), selected = character(0), server = TRUE)
updateSelectizeInput(session, 'digit_choice', choices = c(1,2,3,4), selected = character(0), server = TRUE)
})
observeEvent(input$lower_choice, {
if (input$lower_choice != "") rval(input$lower_choice)
})
observeEvent(input$upper_choice, {
if (input$upper_choice != "") rval(input$upper_choice)
})
observeEvent(input$digit_choice, {
if (input$digit_choice != "") rval(input$digit_choice)
})
}
shinyApp(ui, server)