Make an input value disappear when another is selected

Hi ,

Is there a way we can make one input value disappear when another one is selected when multiple = TRUE? In the example below, the default selected value is "All". I want to set the code such that when any other option is selected, "All" automatically disappears from the selection but not the choices.

library(shiny)
ui <- fluidPage(
  selectInput("variable", "Variable:",
              c("All",
                "Cylinders" = "cyl",
                "Transmission" = "am",
                "Gears" = "gear"),
              multiple = TRUE,
              selected = "All")
)
server <- function(input, output, session) {
}
shinyApp(ui, server)

Yes, this can be accomplished using updateSelectInput(). In the server code below, the observeEvent() triggers any time an input is changed. If there is more than one input and "All" is one of the inputs, Selected is updated to remove it from the group. Finally, Selected is used to update the input.

server <- function(input, output, session) {
  
  observeEvent(input$variable, {
    
    Selected = input$variable
    
    if(length(Selected) > 1 & 'All' %in% Selected) {
      Selected = Selected[Selected != 'All']
    }
    
    updateSelectInput(session = session,
                      inputId = 'variable',
                      selected = Selected)
    
  }, ignoreNULL = T)
  
}
1 Like

Thanks a lot Scotty, this worked well. Another question though, what if I have a long list and I want to go back to "All". Is there a way in which clicking on "All" would deselect the others? I know I can have the "Select all" or "Deselect all" options, but I don't want to use them.

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  pickerInput("variable", "Variable:",
              c("All", LETTERS),
              multiple = TRUE,
              selected = "All")
)

server <- function(input, output, session) {
  
  observeEvent(input$variable, {
    
    Selected = input$variable
    
    if(length(Selected) > 1 & 'All' %in% Selected) {
      Selected = Selected[Selected != 'All']
    }
    
    updatePickerInput(session = session,
                      inputId = 'variable',
                      selected = Selected)
    
  }, ignoreNULL = T)
  
}
shinyApp(ui, server)

I believe the code below provides the functionality you describe.

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  pickerInput("variable", "Variable:",
              c("All", LETTERS),
              multiple = TRUE,
              selected = "All")
)

server <- function(input, output, session) {
  
  # tracks the last selection made (starts as NULL)
  last_selection = reactiveValues(d = NULL)
  
  # observe each time a selection is made
  observeEvent(input$variable, {

    Selected = input$variable
    
    # determines which option was just selected
    new_selection = setdiff(Selected, last_selection$d)
    
    if(length(new_selection) > 0) {
      # if latest selection is "All", only keep "All"
      if(new_selection == 'All') {
        Selected = 'All'
      # if latest selection is not "All", keep everything except "All"
      } else {
        Selected = Selected[Selected != 'All']
      }
    }
    
    # update the input
    updatePickerInput(session = session,
                      inputId = 'variable',
                      selected = Selected)
    
    # update the last selection made
    last_selection$d <<- Selected

  }, ignoreNULL = F)

}

shinyApp(ui, server)
1 Like

OH WOW!!!! YOU == GENIOUS! It works perrrrrrrrrrrfectly Scott, thanks a lot sir :dancer: :dancer: :dancer:

Hi @scottyd22, thank for your help so far. One last question. Now assume we have two input variables (I actually have about 6). I don't want to keep repeating myself for each one (as shown below). Is there a way I can wrap the observeEvent function in a user defined function that only takes in the inputId as an argument?

library(shiny)
ui <- fluidPage(
  selectInput("variable1", "Variable1:",
              c("All", "Cylinders" = "cyl", "Transmission" = "am", "Gears" = "gear"),
              multiple = TRUE,
              selected = "All"), 
  selectInput("variable2", "Variable2:",
              c("All", LETTERS),
              multiple = TRUE,
              selected = "All")
)

server <- function(input, output, session) {
  
## variable 1

  # tracks the last selection made (starts as NULL)
  last_selection1 = reactiveValues(d = NULL)
  
  # observe each time a selection is made
  observeEvent(input$variable1, {
    
    Selected = input$variable1
    
    # determines which option was just selected
    new_selection = setdiff(Selected, last_selection1$d)
    
    if(length(new_selection) > 0) {
      # if latest selection is "All", only keep "All"
      if(new_selection == 'All') {
        Selected = 'All'
        # if latest selection is not "All", keep everything except "All"
      } else {
        Selected = Selected[Selected != 'All']
      }
    }
    
    # update the input
    updatePickerInput(session = session,
                      inputId = 'variable1',
                      selected = Selected)
    
    # update the last selection made
    last_selection1$d <<- Selected
    
  }, ignoreNULL = F)
  
  
  ## variable 2
  
  # tracks the last selection made (starts as NULL)
  last_selection2 = reactiveValues(d = NULL)
  
  # observe each time a selection is made
  observeEvent(input$variable2, {
    
    Selected = input$variable2
    
    # determines which option was just selected
    new_selection = setdiff(Selected, last_selection2$d)
    
    if(length(new_selection) > 0) {
      # if latest selection is "All", only keep "All"
      if(new_selection == 'All') {
        Selected = 'All'
        # if latest selection is not "All", keep everything except "All"
      } else {
        Selected = Selected[Selected != 'All']
      }
    }
    
    # update the input
    updatePickerInput(session = session,
                      inputId = 'variable2',
                      selected = Selected)
    
    # update the last selection made
    last_selection2$d <<- Selected
    
  }, ignoreNULL = F)
  

  
}

shinyApp(ui, server)

This question should be opened as a new topic.

1 Like

Thank you Scotty.

I have opened a new topic here.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.