Search code examples
rshinyshinydashboard

Shiny widget not appearing in sidebarPanel


I am using shinydashboard::sidebarSearchForm in a Shiny app and would like to place other widgets below it. However, whenever I do, they are pushed out of the sidebarPanel and into the whitespace below the sidebar. In the code the code below, the materialSwitch is in sidebarPanel but renders outside of the sidebar. If you put the materialSwitch above the sidebarSearchForm in the sidebarPanel though, then all the widgets are correctly contained in the sidebar. How do I ensure all these widgets stay in the sidebar? I want the materialSwitch to be at the bottom of the sidebar.


library(shiny)
library(shinydashboard)
library(shinyWidgets)

ui <- tagList(
  navbarPage(
    theme = "simplex",
    "App",
    tabPanel("Do something",
             sidebarPanel(
               
               sliderInput("slider", "Select Num:"
                           ,min   = 1
                           ,max   = 10
                           ,sep   = ""
                           ,value = c(1, 10)),
               
               pickerInput(
                 inputId  = "picker",
                 label    = "Select:",
                 selected = "a",
                 choices  = letters,
                 options  = list(
                   `actions-box` = TRUE,
                   size = 10,
                   `selected-text-format` = "count > 3"
                 ),
                 multiple = TRUE
               ),

               h5(HTML("<b>Search</b>")),
               sidebarSearchForm(textId   = "searchText", 
                                 buttonId = "searchButton",
                                 label    = "Include These"
               ),
               
               h5(HTML("<b>Additional Options:</b>")),
               materialSwitch(inputId = "add",
                              label   = "Add?:?", 
                              value   = FALSE, 
                              status  = "primary")
             ),
             
             mainPanel(
               tabsetPanel(
                 tabPanel("Tab",
                          "text"
                 )
               )
             )
    )
  )
)

server <- function(input, output){
}


Solution

  • Reason for this behaviour

    The problem arises from the fact that both, sidebarPanel as well as sidebarSearchForm create a <form> tag and <form>tags must not include other <form> tags. In chrome for example such invalid HTML is fixed and my guess is that this fixing moves the element out of the sidebar.

    BTW: sidebarSearchForm is meant to be used in a dashboardSidebar (which does not create a <form> tag.


    Workaround

    I am not an HTML expert, so I do not know whether the sidebarSearchForm needs to sit in its own <form> (nor did I use this element in the past).

    Assuming that it is not necessary to have it in an own <form>, you can tweak sidebarSearchForm like this:

    mySidebarSearchForm <- function (textId, buttonId, label = "Search...", icon = shiny::icon("search")) {
       div(class = "sidebar-form", div(class = "input-group", 
            tags$input(id = textId, type = "text", class = "form-control", 
                placeholder = label, style = "margin: 5px;"), 
            span(class = "input-group-btn", tags$button(id = buttonId, 
                type = "button", class = "btn btn-flat action-button", 
                icon))))
    }
    

    (This is basically a copy of the original sidebarSearchForm replacing the <form> by <div>)

    Then the UI renders as it should:

    ui <- tagList(
      navbarPage(
        theme = "simplex",
        "App",
        tabPanel("Do something",
                 sidebarPanel(
                   mySidebarSearchForm(textId   = "searchText", 
                                     buttonId = "searchButton",
                                     label    = "Include These"
                   ),
                   actionButton("go", "go")
    
                 ), 
                 mainPanel(
                   tabsetPanel(
                     tabPanel("Tab",
                              "text"
                     )
                   )
                 )
        )
      )
    )
    
    shinyApp(ui, server = function(...) {})
    

    enter image description here