1
votes

Goal: When the user types a query in selectize input, I'd like to filter the drop-down based on the usual string matching but also based on a custom similarity metric. For instance, if the user types 'Obama', I'd like the suggestions to contain 'Barack Obama', 'Obamacare', etc. (string matching) but also 'president' or 'politician' (synonyms).

Setting: the list of synonyms is returned in real-time by some function in server.R that takes what the user has typed as input. I think I need to use the 'Server-side selectize' approach described in this tutorial: https://shiny.rstudio.com/articles/selectize.html:

The client-side selectize input relies solely on JavaScript to process searching on typing. The server-side selectize input uses R to process searching, and R will return the filtered data to selectize. To use the server version, you need to create a selectize instance in the UI, and update it to the server version

Problem:

  • how can I access the character string as it is being typed by the user in the text box to feed my function?
  • how can I get the updateSelectizeInput function to take the list of synonyms returned by my function into account?
1
Show us what you did so far,...Tonio Liebrand

1 Answers

0
votes

how can I access the character string as it is being typed by the user in the text box to feed my function?

Selectize doesn't send that data back to shiny by default. You need to fetch it with JS.

Fortunately, shiny allows us to pass options to the selectize constructor. Looking at the selectize documentation, load and onType seem promising. These both get called for each input event.

how can I get the updateSelectizeInput function to take the list of synonyms returned by my function into account?

You can then get your JS to inform shiny of the value of the selectize textbox with a JS-controlled input and use that to drive your updateSelectizeInput function. See communicating with js.

You could also just skip updateSelectizeInput and manipulate the options from javascript directly if you give JS the list of new options, but that seems more complicated. If you want to do it that way you'll need to use this.removeOption or something to get rid of old values (API docs).

Demo of adding custom JS to a selectize element

library(shiny)

ui <- fillPage(
  selectizeInput("demo", "Filter with custom function",
                 c("Pre", "Provided", "Options"),
                 options = list(
                   load = I('function(input, callback) {
                                // input is the text in the select widget.
                                // callback in this case adds elements to the option list.

                                console.log(input, this)
                                callback([{"label": "Populated from js", "value": "Populated"}])
                            }'))
                 )
  )

server <- function(input, output) {
}

# Run the application
shinyApp(ui = ui, server = server)