Home > Software design >  Shiny : keep the value in the mainpanel
Shiny : keep the value in the mainpanel

Time:12-22

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 selectizeInputs 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 observeEvents 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)

enter image description here

  • Related