When using bslib::accordion()
and bslib::accordion_panel()
, as below, I have an accordion with s (say s=3
) panels. I want each of the accordion_panels to contain an accordion, which itself contains t (say t=2
) panels. No problem constructing this, as below:
library(shiny)
library(bslib)
accordion(
accordion_panel(
title = "panel_1",
accordion(
accordion_panel(title = "panel_1_sub_1", HTML("panel 1, subpanel 1 content")),
accordion_panel(title = "panel_1_sub_2", HTML("panel 1, subpanel 2 content")),
open=FALSE,
multiple=FALSE # this is not working
)
),
accordion_panel(
title = "panel_2",
accordion(
accordion_panel(title = "panel_2_sub_1", HTML("panel 2, subpanel 1 content")),
accordion_panel(title = "panel_2_sub_2", HTML("panel 2, subpanel 2 content")),
open=FALSE,
multiple=FALSE # this is not working
)
),
accordion_panel(
title = "panel_3",
accordion(
accordion_panel(title = "panel_3_sub_1", HTML("panel 3, subpanel 1 content")),
accordion_panel(title = "panel_3_sub_2", HTML("panel 3, subpanel 2 content")),
open=FALSE,
multiple=FALSE # this is not working
)
),
open=FALSE,
multiple=FALSE # this is working fine
)
Upon initiation, all three panels and each of the nested accordions are closed. As requested on the outer/parent accordion, only one accordion panel is allowed to be open multiple=FALSE
, and this works well.
However, although each of the inner accordions also have multiple=FALSE
, multiple panels within these inner accordions do open (i.e. the panels in the inner accordion do not automatically close when another panel within that inner accordion is selected).
Anyone know a work-around for this, or is there something I am doing incorrectly in the above design of a nested accordion?
The reason why the inner accordion_panel
stay open is that they get multiple parents (attribute data-bs-parent
) assigned when they are created. E.g. for your first nested accordion
, the parents look like this:
[1] "#bslib-accordion-7599" # "panel_1"
[1] "#bslib-accordion-5703 #bslib-accordion-7599" # "panel_1_sub_1"
[1] "#bslib-accordion-5703 #bslib-accordion-7599" # "panel_1_sub_2"
However, only the first one is the "real" parent. This has to be fixed in bslib
. As long as #819 is open, you can use the following workaround.
The idea is that we have to drop all parts of the data-bs-parent
attribute except the first one. Your accordion
from above is, say, nestedAcc
, then we manipulate it using htmltools::tagQuery
:
nestedAcc <- accordion( # defined as in the question
accordion_panel(
...
)
)
tagQ <- htmltools::tagQuery(nestedAcc)
tagQ$
find(".accordion-collapse.collapse")$
each(function(el, i) {
# save all parents
parents <- el$attribs[names(el$attribs) == "data-bs-parent"]
# remove all parents
el$attribs <- el$attribs[names(el$attribs) != "data-bs-parent"]
# append the "true" parent, which is the first one
tagAppendAttributes(el, `data-bs-parent` = unlist(parents)[1])
# return edited tag
el
})$
allTags()
This yields an accordion
where the inner panels have multiple = FALSE
.