Shiny selectizeInput: Read current text

Viewed 254

With the Shiny selectizeInput widget, the user can type in text as well as select a value from a list of values. Is there a way in R to read the current value of the text?

(Added) I should make it clear that I want to be able to read the text the user enters before he has made a selection. As zimia points out, after he has made a selection, the value of whatever he selected becomes available as input$input_id (assuming that the selectize input has the id "input_id").

3 Answers

you can just use the input$input_id. See below

ui <- fluidRow(
  selectizeInput("input1","Enter Text",choices=c("A","B") ,options = list(create=TRUE)),
  textOutput("output1")
)

server<- function(input, output, session){
  output$output1 <- renderText({
    req(input$input1)
    input$input1
  })
}

I was thinking that there would be a solution at the level of R/shiny. But I have found a solution that uses javascript.

    library(shiny)
    js <- '
      $(document).on("keyup", function(e) {
        minChars = 4;
        tag1 = document.activeElement.getAttribute("id");
        val1 = document.activeElement.value;
        if (tag1 == "input1-selectized") {
          if (Math.sign(val1.length +1 - minChars) == 1) {
            obj = { "val": val1 };
            Shiny.onInputChange("valueEntered", obj);
          }
        }
      });
'
      ui <- fluidRow(
        tags$script(js),
        selectizeInput(
          "input1", 
          "Enter text", 
          choices = c("A", "B"), 
          options = list(create = FALSE)),
        textOutput("output1")
      )

      server <- function(input, output, session) {
        output$output1 <- renderText({
          req(input$valueEntered$val)
          input$valueEntered$val
        })
      }
  
      shinyApp(ui = ui, server = server)

The javascript looks for text entered into the element with id "input1-selectized", and if the value is length 4 or more, sets the shiny variable "valueEntered" to an object with val = the text.

Then the observeEvent uses the shiny variable input$valueEntered to set the output text.

The reason in the javascript for using the Math.sign function rather than >, and the reason for nested if's is because for some reason, Shiny replaces infix operators such as > and && by their html equivalents, > and &&.

Note that if the selectizeInput widget has id "input1", then the corresponding text field has id "input1-selectized".

Shiny's selectizeInput still gives access to the internal properties, methods and callbacks of Selectize.js through "options" argument of updateSelectizeInput. Selectize.js exposes callback "onType", so you can use like that:

updateSelectizeInput(
  session,
  'input1',
  options = list(
    onType = I('
      text => Shiny.setInputValue("input1_searchText", text)
    '),
    onBlur = I('
      () => Shiny.setInputValue("input1_searchText", null)
    ')
  )
)

and consume it with observer:

observeEvent(input$input1_searchText, {
  print(input$input1_searchText)
  }, ignoreNULL = FALSE
)

Please, note, that I was also interested to know when the select looses focus and hence used "onBlur" event to set the search text to NULL.

Related