drmariod drmariod - 9 days ago 4
R Question

search field in shiny navbarPage

I am trying to get a global search field into my

navbarPage
after some
tabPanel
. I am not sure if it is possible, since all my tests producing the
textInput
outside the
navbar
.

The rStudio shiny layout guide points to the bootstrap navbar documentation , where they actually did exactly this. But I am not able to reproduce it with my shiny app.

library(shiny)

ui <- shinyUI(
shiny::navbarPage('test',
shiny::tabPanel('my app',
fluidPage(

# Application title
titlePanel("Old Faithful Geyser Data"),

# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),

# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
))),

### Still inside navbarPage
shiny::textInput("text",
label=h3("Text input"),
value="should be inside the navbar!")
))

server <- function(input, output, session) {
output$distPlot <- renderPlot({

# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)

# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')

})
}

shinyApp(ui, server)

Answer

You can do this by manipulating the navbar HTML a little bit. Valter is correct - you can achieve this by constructing the menu entirely in HTML instead of using Shiny. But there's an easier way: you can build the navbar in regular Shiny, and then use htmltools to slightly modify it. Here's one quick solution that I think is the cleanest out of the current proposed solutions:

library(shiny)

navbarPageWithInputs <- function(..., inputs) {
  navbar <- navbarPage(...)
  form <- tags$form(class = "navbar-form", inputs)
  navbar[[3]][[1]]$children[[1]] <- htmltools::tagAppendChild(
    navbar[[3]][[1]]$children[[1]], form)
  navbar
}

ui <- navbarPageWithInputs(
  "Test app",
  tabPanel("tab1", "tab 1", textOutput("out")),
  tabPanel("tab2", "tab 2"),
  inputs = textInput("search", NULL, placeholder = "Search")
)

server <- function(input, output, session) {
  output$out <- renderText(input$search)
}

shinyApp(ui = ui, server = server)

Basically I created a navbarPageWithInputs() function that accepts all the same parameters as navbarPage(), and also an inputs parameter. All this function does is call the regular navbarPage(), and then adds the given inputs to the HTML.

Comments