Question

Originally I create this shiny interface that takes in a parameter "company id" and "date", but here we have a problem: most people dont know the companies we work with by their id, only their name, i.e. (McDonalds, Radioshack).

So I want to ideally create a search function like this enter image description here

My current idea is to pass in a table including a list of all our partner companies and their ids to global.R. Then pass in the textInput as the search variables and perform the search on server side. However, I get lost on how to pass searchResults back into the UI on a selectInput panel?

My current code:

ui.R

library(shiny)

shinyUI(pageWithSidebar(


  sidebarPanel(

    textInput("nameSearch", "Or, Search for company name", 'McDonald'),
    selectInput("partnerName", "Select your choice", list( "searchResults" ),
    br(),
    submitButton("Update View"),
    br(),

  ),

server.R

  shinyServer(function(input, output) {

  #subTable
  searchResult<- reactive({
    subset(partners, grepl(input$nameSearch, partners$name))
  })

  output$searchResults <- renderTable({ 
    searchResult[,1]
    })

global.R

partners<- read.csv("partnersList.csv", fill=TRUE)

partnersList is just in this format

    name            id 
 ------------------
    McDonalds        1
    Wendy's          2
    Bestbuy          3 
Was it helpful?

Solution

You need to make the UI reactive. I haven't tested this (miss data for it too) but should work I think. In server.R add:

output$selectUI <- renderUI({ 
selectInput("partnerName", "Select your choice", searchResult()[,1] ),
})

And in ui.R replace the selectInput with:

htmlOutput("selectUI")

OTHER TIPS

In Shiny version 0.8 (where I have tested it), in server.R add the following:

shinyServer(function(input, output, session) {

  observe({
    # This will change the value of input$partnerName to searchResult()[,1]
    updateTextInput(session, "partnerName", 
                    label = "Select your choice", 
                    value = searchResult()[,1])
  })

})

Now the function within shinyServer has additional argument session.

You can skip the label if you don't need to change it.

You don't need to change anything in ui.R.

Reply from Rstudio's JC:

Sure, just use a textInput for the search string, and use renderUI/uiOutput to make a dynamic selectInput. Then the rest of your code can depend on the selectInput's value. (Make sure to check for NULL or whatever when reading the selectInput value, because it will start out with no value.)

If I understand the question correcly, all you need to do is display to the user company names and have company ids passed to the server.

I suppose this feature was not available back in the days (and you had to work around as suggested above) but nowadays the argument choices in selectInput function accepts named lists exactly for this need. Hopefully example below clarifies the situation.

library(shiny)
library(tidyverse)

companies <- tribble(
    ~name, ~id,
    "McDonalds", 1,
    "Wendy's", 2,
    "Bestbuy", 3
)

ui <- fluidPage(
    uiOutput("select_company_ui"),
    textOutput("value")
)

server <- function(input, output) {
    output$select_company_ui <- renderUI({
        selectInput("select_company", "Select company", choices = deframe(companies))
    })
    
    output$value <- renderText(paste0("Value of the company filter is ", input$select_company))
}

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

Here you can see the resulting app:

enter image description here

Side note: I use function deframe from package tibble to turn a tibble into a named list just for convenience, you could do without it by writing

choices = c("McDonalds" = 1, "Wendy's" = 2, "Bestbuy" = 3)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top