Search code examples
rshinyselectize.jsselectinput

R shiny selectInput - preselect list begins only with the letters written in inputfield


Hei,

I have a very long list of headers (>1000 items). I want to chose one of them with a selectInput in a R shiny app. Before chosing one Item, I want to type letters in the selectInput to shorten the list of headers. This is the usual behaviuor of selectInput.

My aim is, that only items are listed in the preselect list which starts with the letters written in the input-field of the selectInput. This is, that the users can work easily like in a dictionary only with headers beginning with a special letter.

For example my headers are:

headers <- c(
    "Apple", "Banana", "Carrot", "Date", "Eggplant", "Fig", "Grape",
    "Honeydew", "Iceberg lettuce", "Jackfruit", "Kiwi", "Lemon",
    "Ananas", "Anis", "Birne", "Bringebaer"
    )

If I type in "A" the list of possible headers should be reduced to "Apple", "Ananas","Anis" and if I type in "B" it should be "Banana","Birne","Bringebaer" only. By typing in "An" it should be "Ananas","Anis".

Is this possible?

My first try is with selectizeInput using argument options:

(The code is generated wih help of ChatGPT, because I am not familiar with javascript)

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  selectizeInput(
    inputId = "header",
    label = "Select Header",
    choices = NULL,
    options = list(
      placeholder = "Type to filter headers...",
      create = TRUE,
      plugins = list("remove_button"),
      filterOption = I("function(phrase, item) { return item.text.startsWith(phrase.toLowerCase()); }")
    )
  ),
  textOutput("selectedHeader")
)

server <- function(input, output, session) {
  # Example list of headers
  headers <- c(
    "Apple", "Banana", "Carrot", "Date", "Eggplant", "Fig", "Grape",
    "Honeydew", "Iceberg lettuce", "Jackfruit", "Kiwi", "Lemon",
    "Ananas", "Anis", "Birne", "Bringebaer"
  )

  # Update the selectizeInput choices based on the filtered headers
  observe({
    updateSelectizeInput(
      session = session,
      inputId = "header",
      choices = headers,
      server = TRUE
    )
  })

  # Render the selected header
  output$selectedHeader <- renderText({
    input$header
  })
}

shinyApp(ui, server)

Another hint was, to use a custom JavaScript function to handle the filtering logic. But here I'm totally lost to understand the code.

Thank you for any help!


Solution

  • The option to define is the score option. It must returns a function which returns a score. Here my function returns 1 for the items which starts with the searching pattern, otherwise 0.

      selectizeInput(
        inputId = "header",
        label = "Select Header",
        choices = NULL,
        multiple = TRUE,
        options = list(
          placeholder = "Type to filter headers...",
          #create = TRUE,
          plugins = list("remove_button"),
          score = I("function(search) { 
            return function(item) {
              return item.label.toLowerCase().startsWith(search) ? 1 : 0 ;
            };
          }")
        )
      ),