Why do bootstrap dropdown menus not function inside of Shiny?

765 views
Skip to first unread message

chris warth

unread,
Sep 10, 2013, 2:31:54 PM9/10/13
to shiny-...@googlegroups.com
Maybe I've overlooked some simple configuration, but it seems like dropdown buttons don't function correctly in Shiny apps.

A bootstrap dropdown button should function like this example here - http://jsfiddle.net/BqKNV/65/

However when I put the same code into a really basic Shiny app, the menu drops down, but does not disappear after a selection is made.


require(shiny)
 
shiny::runApp(list(
ui = bootstrapPage(
div(HTML("I like <u>turtles</u>")),
with(tags,
div(class="dropdown btn-group",
a("Action", class="btn dropdown-toggle", "data-toggle"="dropdown", href="#"),
ul(class="dropdown-menu",
li(a("Foo", href="#")),
li(a("Bar", href="#"))
)
)
)
),
server = function(input, output) { }
))

Winston Chang

unread,
Sep 10, 2013, 5:39:44 PM9/10/13
to shiny-...@googlegroups.com
The difference is that your example uses bootstrap 2.3.2, while Shiny includes 2.1.0. Here's a modified version of your fiddle that uses 2.1.0:

Offhand, I'm not sure there's a simple solution for it. One possibility is that could do is write a modified version of bootstrapPage.

-Winston


--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

ZJ

unread,
Sep 11, 2013, 1:27:38 AM9/11/13
to shiny-...@googlegroups.com
I have not tried this yet but suppose you are using the index.html instead of ui.R then you can switch between all the different versions of bootstrap or even use another frontend framework right?

chris warth

unread,
Sep 11, 2013, 1:44:10 AM9/11/13
to shiny-...@googlegroups.com

Thanks for looking, I wouldn't have noticed that.
It might be possible for me to forcibly clear the menu from the event callback.   I guess I'll look into how 2.3.2 does it.

chris warth

unread,
Sep 11, 2013, 8:44:59 PM9/11/13
to shiny-...@googlegroups.com
I took your suggestion and made my own version of bootstrapPage().  This seems to work well when running Shiny locally, but does not seem to work when run from inside Shiny server.    Don't know why yet.

Code on Shiny server:  https://gist.github.com/cswarth/6531813

Locally things are much better.  Dropdown buttons now work, and the rest of the Shiny app seems to still be functional.  Thanks again for your help.

Winston Chang

unread,
Sep 14, 2013, 6:24:04 PM9/14/13
to shiny-...@googlegroups.com
The reason it's not working is probably because of the way that bootstrapPage is defined in your code: you're not replacing shiny::bootstrapPage; instead, you're defining another copy of it in the global environment.

pageWithSidebar is defined in the shiny namespace, so when it calls bootstrapPage, R first searches in the shiny namespace for that function. It finds the function there before it finds your version of the function. So you also need to define your own version of pageWithSidebar -- which have identical code to the shiny version of the function (it will just have a different environment).

You can define the whole pageWithSidebar function, or you can do this to copy the shiny::pageWithSidebar function, and the change its environment:
  pageWithSidebar <- shiny::pageWithSidebar
  environment(pageWithSidebar) <- environment()


-Winston


chris warth

unread,
Sep 17, 2013, 3:28:39 PM9/17/13
to shiny-...@googlegroups.com
Thanks Winston, before I saw your message I stumbled across reassignInPackage() in R.utils.   That seem to do the trick for replacing bootstrapPage which takes care of pageWithSidebar and friends.

## call with explicit package name to avoid pollution the namespace if we don't have to.
R.utils::reassignInPackage("bootstrapPage", pkgName="shiny", mybootstrapPage)

BTW, the bug in bootstrap V2.1.0 that prevents dropdown menus from clearing is actually fixed in the very next point release, V2.1.1.   I don't know the specific change that fixed it (85 changed files, IIRC) but that seems to be enough to fix dropdown menus.  I'm still advancing to V2.3.2 because it seems to work with shiny and maybe I'll get some other fixes as well.

So now I have dropdown button menus working in Shiny -- sort of - I'll post another question that is specific to the inputBinding problems I am seeing.

chris warth

unread,
Sep 18, 2013, 2:43:23 PM9/18/13
to shiny-...@googlegroups.com
This is hopefully a final follow-up to my question.   User Vincent has posted a shiny app that uses a bootstrap navbar control, a close cousin of dropdown buttons.   He has code in the Shiny.InputBinding for the control that explicitly clears the menu after an item is selected.  Perhaps this is the way you were expected to do it back when bootstrap V2.1.0 was current.  

Vincent's app can be found here: http://vnijs.rady.ucsd.edu:3838/marketing/

The relevant portion of the code is in inst/marketing/www/js/navbar.js

  subscribe: function(el, callback) {
    $(el).on("click.navbarBinding", "a[data-value]", function(e) {
      $(el).data("nav-value", $(e.target).data("value"));
      $('.dropdown.open').removeClass('open');
      callback();
    });

Note the explicit call to removeClass(). That is necessary to close the menu on v2.1.0 of bootstrap.

Reply all
Reply to author
Forward
0 new messages