3

I have a selectizeInput with multiple = TRUE in a shiny application and I would like to prevent the user from selecting NULL (i.e., from leaving it blank). My goal is to ensure that at least one item is selected (no matter which one).

I found this question on the opposite problem (i.e., limiting maximum number of selections) and I checked selectize documentation. Unfortunately, there seem to be no minItems option. Is there a way to achieve my desired functionality?

Minimum example:

library(shiny)
shinyApp(

  ui = fluidPage(
    selectizeInput(
      inputId = "testSelect",
      label = "Test",
      choices = LETTERS[1:4],
      selected = LETTERS[1],
      multiple = TRUE,
      # Problem: how to specify 'minItems' here
      options = list(maxItems = 2)
    ),
    verbatimTextOutput("selected")
  ),

  server = function(input, output) {
    output$selected <- renderPrint({
      input$testSelect
    })
  }

)
Tonio Liebrand
  • 17,189
  • 4
  • 39
  • 59
pieca
  • 2,463
  • 1
  • 16
  • 34

1 Answers1

5

Seems to be an open issue: #https://github.com/selectize/selectize.js/issues/1228.

Concerning your R/Shiny implementation you could use a workaround with renderUI().

You would build the input on the server side and control the selected choices. Before you build the input on the server side you can check the current value and if it does not fulfill your requirement you can overwrite it:

selected <- input$testSelect
if(is.null(selected)) selected <- choices[1]

Reproducible example:

library(shiny)
choices <- LETTERS[1:4]  
shinyApp(
  ui = fluidPage(
    uiOutput("select"),
    verbatimTextOutput("selected")
  ),
  server = function(input, output) {
    output$selected <- renderPrint({
      input$testSelect
    })

    output$select <- renderUI({
      selected <- input$testSelect
      if(is.null(selected)) selected <- choices[1]
      selectizeInput(
        inputId = "testSelect",
        label = "Test",
        choices = choices,
        selected = selected,
        multiple = TRUE,
        options = list(maxItems = 2)
      )
    })
  }
)
Tonio Liebrand
  • 17,189
  • 4
  • 39
  • 59
  • thank you for accepting. Feel free to upvote. Or ist there still something that can be added? – Tonio Liebrand Jun 27 '18 at 20:34
  • 2
    Thanks, this helped to solve my problem. The only thing that can be added: I think it is more natural to replace null by the last non-null value (i.e., if you attempt to remove "B", the code will get "B" back rather than always "A" (choices[1])). I achieved than with adding to sever: `nonNull <- reactiveVal("A"); observeEvent(input$testSelect, {nonNull(input$testSelect)})` and changing 'replacing' code to: `if(is.null(selected)) selected <- nonNull()` – pieca Jun 28 '18 at 06:18