diff --git a/DESCRIPTION b/DESCRIPTION index c0b2467..5665472 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -34,7 +34,7 @@ Imports: URL: https://github.com/ijlyttle/bsplus BugReports: https://github.com/ijlyttle/bsplus/issues Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.1 +RoxygenNote: 7.2.3 Encoding: UTF-8 Suggests: testthat, shiny, diff --git a/NAMESPACE b/NAMESPACE index 935e4fb..c46d4af 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -15,6 +15,7 @@ S3method(bs_set_opts,default) S3method(bs_set_opts,shiny.tag) export("%>%") export(bs_accordion) +export(bs_accordion_multi) export(bs_accordion_sidebar) export(bs_append) export(bs_attach_collapse) diff --git a/R/bs_accordion_multi.R b/R/bs_accordion_multi.R new file mode 100644 index 0000000..fb6ba6c --- /dev/null +++ b/R/bs_accordion_multi.R @@ -0,0 +1,102 @@ +#' Allow multiple `bs_accordion` sections to be open, and specify which ones start as open +#' +#' @param X shinyBS::bs_accordion object +#' @param multi logical Should more than one panel be permitted to be open at one time. +#' @param open integer vector Indices of panels that should be open when the page loads. +#' +#' @return Modified shinyBS::bs_accordion object +#' +#' @export +#' +#' @examples +#' +#' if(interactive()) +#' { +#' library(shiny) +#' library(bsplus) +#' +#' shinyApp( +#' ui = fluidPage( +#' +#' tags$header( +#' tags$style( +#' HTML( +#' ' +#' .panel-heading.collapsed > .panel-title:before { +#' float: right !important; +#' padding-right: 5px; +#' content:"+" +#' } +#' +#' .panel-heading > .panel-title:before { +#' float: right !important; +#' font-family: FontAwesome; +#' padding-right: 5px; +#' content:"-" +#' } +#' ' +#' ) +#' ) +#' ), +#' +#' tags$h2("Multiple Open Panels, Panels 1 and 3 open at page load"), +#' bs_accordion(id = "beatles") %>% +#' bs_set_opts(panel_type = "success", use_heading_link = TRUE) %>% +#' bs_append(title = "John Lennon", content = "Rhythm guitar, vocals") %>% +#' bs_append(title = "Paul McCartney", content = "Bass guitar, vocals") %>% +#' bs_append(title = "George Harrison", content = "Lead guitar, vocals") %>% +#' bs_append(title = "Ringo Starr", content = "Drums, vocals") %>% +#' bs_accordion_multi( +#' multi=TRUE, +#' open=c(1,3) +#' ), +#' +#' tags$h2("One Open Panel, No panels open on page load."), +#' bs_accordion(id = "fruit") %>% +#' bs_set_opts(panel_type = "info") %>% +#' bs_append(title = "Apples", content = "An apple a day keeps the doctor away.") %>% +#' bs_append(title = "Bannana", content = "Watch out for bannana peels!") %>% +#' bs_append(title = "Kumquat", content = "What is a kumquat?!") %>% +#' bs_accordion_multi( +#' multi=FALSE, +#' open=c() +#' ) +#' ), +#' +#' server = function(input, output) {} +#' ) +#' +#' } +#' +bs_accordion_multi <- function(X, multi=TRUE, open=1) { + for(i in 1:length(X$children)) + { + if(multi) + # Remove 'data-parent' attribute so multiple panels can be open at once + X$children[[i]]$children[[1]]$attribs$`data-parent` <- NULL + + # Remove 'in' class to prevent *any* panel from starting as open + classAttribs <- which(names(X$children[[i]]$children[[2]]$attribs) == "class") + for(j in classAttribs) + { + if(X$children[[i]]$children[[2]]$attribs[j]=="in") + { + X$children[[i]]$children[[2]]$attribs[j] <- NULL + } + } + + if(i %in% open) + { + # Add 'in' class (back) to panels selected to start as open + X$children[[i]]$children[[2]]$attribs <- append(X$children[[i]]$children[[2]]$attribs, list(class="in")) + } + else + { + # Add 'collapsed' class to panels slected to start as closed, so css rules work properly + X$children[[i]]$children[[1]]$attribs <- append(X$children[[i]]$children[[1]]$attribs, list(class="collapsed")) + } + } + + X + +} diff --git a/man/bs_accordion_multi.Rd b/man/bs_accordion_multi.Rd new file mode 100644 index 0000000..bdc2fc2 --- /dev/null +++ b/man/bs_accordion_multi.Rd @@ -0,0 +1,82 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/bs_accordion_multi.R +\name{bs_accordion_multi} +\alias{bs_accordion_multi} +\title{Allow multiple \code{bs_accordion} sections to be open, and specify which ones start as open} +\usage{ +bs_accordion_multi(X, multi = TRUE, open = 1) +} +\arguments{ +\item{X}{shinyBS::bs_accordion object} + +\item{multi}{logical Should more than one panel be permitted to be open at one time.} + +\item{open}{integer vector Indices of panels that should be open when the page loads.} +} +\value{ +Modified shinyBS::bs_accordion object +} +\description{ +Allow multiple \code{bs_accordion} sections to be open, and specify which ones start as open +} +\examples{ + +if(interactive()) +{ +library(shiny) +library(bsplus) + +shinyApp( + ui = fluidPage( + + tags$header( + tags$style( + HTML( + ' + .panel-heading.collapsed > .panel-title:before { + float: right !important; + padding-right: 5px; + content:"+" + } + + .panel-heading > .panel-title:before { + float: right !important; + font-family: FontAwesome; + padding-right: 5px; + content:"-" + } + ' + ) + ) + ), + + tags$h2("Multiple Open Panels, Panels 1 and 3 open at page load"), + bs_accordion(id = "beatles") \%>\% + bs_set_opts(panel_type = "success", use_heading_link = TRUE) \%>\% + bs_append(title = "John Lennon", content = "Rhythm guitar, vocals") \%>\% + bs_append(title = "Paul McCartney", content = "Bass guitar, vocals") \%>\% + bs_append(title = "George Harrison", content = "Lead guitar, vocals") \%>\% + bs_append(title = "Ringo Starr", content = "Drums, vocals") \%>\% + bs_accordion_multi( + multi=TRUE, + open=c(1,3) + ), + + tags$h2("One Open Panel, No panels open on page load."), + bs_accordion(id = "fruit") \%>\% + bs_set_opts(panel_type = "info") \%>\% + bs_append(title = "Apples", content = "An apple a day keeps the doctor away.") \%>\% + bs_append(title = "Bannana", content = "Watch out for bannana peels!") \%>\% + bs_append(title = "Kumquat", content = "What is a kumquat?!") \%>\% + bs_accordion_multi( + multi=FALSE, + open=c() + ) + ), + + server = function(input, output) {} + ) + +} + +}