ijlyttle / bsplus Goto Github PK
View Code? Open in Web Editor NEWShiny and R Markdown addons to Bootstrap 3
Home Page: http://ijlyttle.github.io/bsplus/
License: Other
Shiny and R Markdown addons to Bootstrap 3
Home Page: http://ijlyttle.github.io/bsplus/
License: Other
It'd be nice to be able to do something like
library(shiny)
library(bsplus)
ui <- fluidPage(
bs_accordion(id = "foo") %>%
bs_append(title = "bar", content = "hello world", selected = FALSE)
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
so that the accordion will initialize in a collapsed state
Per @sctyner, it would be useful to embed modals into things that are not html_document() or shiny apps, in this case, ioslides. Following Kyle Walker, I think htmlwidgets are the way to go.
Components to turn into widgets (list may grow):
There are places that I am not using the official htmltools API; I should probably note those here:
If we had these functions, I could avoid the abuse:
tagSetAttributes()
- clears and sets, rather than appends attributestagName()
- gets the name of the tag, i.e. "div", "button"bs_accordion(id="id1") %>%
bs_append(title="Check this", content="This is so cool.")
Instead of just the text, can I add code chunks with formatting into the content? Also, how do I set the state (collapsed/non-collapsed)?
It could be useful to be able to collapse shiny Inputs - the thought is that we would have a
shinyInput_embed_collapse(tag)
This would take a shinyInput and return a modified copy of the shinyInput.
The modifications would:
add a caret to the left side of the label of the shiny input.
the caret would be wrapped in a link.
the link would be associated with a collapse element that wraps the rest of the shiny input.
the caret would rotate according to if the input is open or not
document
test
article
app
I have to create an accordion list made up of the column names in a dataframe and the content of each accordion as the factor levels of the column. I can list individual append statements for each column and work with it but that is too tedious and is not practical if I don't have any knowledge about the dataframe. Is there any way to do this using some kind of a loop?
The code I wrote for this is below:
library(shiny)
library(shinydashboard)
library(bsplus)
library(datasets)
facts <- colnames(CO2)[sapply(colnames(CO2), is.character)]
# Define UI for application
ui <- fluidPage(
#What I want to do
# bs_accordion(id = "test"),
# lapply(facts, function(x){
# bs_append(tag = "test", title = x, ccheckboxGroupInput("t", "", choices = unique(CO2[[x]])))
# })
#
##What works
bs_accordion(id = "test1")%>%
bs_append(title = facts[1], checkboxGroupInput("t1", "", choices = unique(CO2[[facts[1]]])))%>%
bs_append(title = facts[2], checkboxGroupInput("t2", "", choices = unique(CO2[[facts[2]]])))%>%
bs_append(title = facts[3], checkboxGroupInput("t3", "", choices = unique(CO2[[facts[3]]])))
#bs_append(title = facts[2], content = list(unique(CO2[[facts[2]]]))) - gives a warning:
# in charToRaw(enc2utf8(text)) :
# argument should be a character vector of length 1
# all but the first element will be ignored
)
# Define server logic
server <- function(input, output) {
}
# Run the application
shinyApp(ui = ui, server = server)
An htmlwidget embedded in a popover does not seem to work:
https://stackoverflow.com/questions/44628631/rmarkdown-embed-sparkline-into-a-bootstrap-popover
See:
https://stackoverflow.com/questions/36409144/execute-js-inside-of-a-bootstrap-popover
For possible solution, but not yet convinced this is in the scope of this package.
Had a request to change the necessary version to 3.2.4 - maybe incorporate this for the next CRAN release?
How to make sure that it actually works using 3.2.4?
stuff left over from formatSE
am i using it wrong?
> packageVersion('bsplus')
[1] ‘0.1.0.9000’
server <- function(input, output) {
}
ui <- fluidPage(
bs_carousel(id = "tabPrev", use_indicators = TRUE) %>%
bs_append(
content = bs_carousel_image(src = file.path(getwd(),"knit/tblDoc.png")),
caption = bs_carousel_caption("tabTest", "rendered table")
)
)
shinyApp(ui = ui, server = server)
Much like useShinyjs - maybe talk to Dean (sorry for "subtweeting") when I figure out which end is up
Hi,
There are cases where modal window should be triggered via observe event other than button clicks. Currently bsplus lacks capability to support such.
Please add.
example: when user clicked 3 times, popup modal to submit an issue.
Maybe this comes out in the next bootstrap, but I would like to be able to use shinyjs such that when a panel is disabled:
Note, a panel would have an Id so that server can use the shinyjs::toggleState()
function
maybe this is a different package?
an id generator to guarantee that you are getting a unique id
accessor methods for id's to use with when attaching
per title
would also be a good way to refamiliarize self with the package
I am developing a rather UI-complex Shiny app, that dynamically creates numericInputs based on what is selected from a ShinyTree. Then, for each numericInput, I am attempting to create a modal dialog using shiny_icon_link. However, when I click the "i" button, the UI dims as if to display the modal - but it doesn't ever display it. It just gets stuck on dim.
I do this by using lapply inside a renderUI function, in the server section to call bs_attachmodal.
I also do an lapply inside the UI section to call bs_modal.
I haven't pasted any code, because I'm not getting an actual error. I can if necessary.
Have there been any known issues or obvious things that one should do when attempting to create a modal like this?
If I try to create a simple accordion without loading the package (without library(bsplus)
), I get an error:
no applicable method for 'bs_attr' applied to an object of class "logical"
Example:
library(shiny)
ui <- fluidPage(
bsplus::bs_append(bsplus::bs_accordion(id = "foo"), title = "bar", content = "hello world")
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
Look like we can either set the display tooltip trigger option to "hover" or default "hover focus".
However even setuping it to "hover" only, it is also unexpectedly displaying with 'focus' state. I am not sure to understand why.
Below an example with SelectInput widget. Select one of the option and move your move elsewhere (the focus state of the SelectInput should remains until we click elsewhere), the tooltip does not go away as we should expect.
library(shiny)
library(bsplus)
ui <- fluidPage(
use_bs_tooltip(),
titlePanel("Hello Shiny!"),
sidebarLayout(
sidebarPanel(
selectInput(inputId ="myid",
label = "list",
choices = c("a", "b", "c", "d"),
selected = "a") %>%
bs_embed_tooltip(title = "stay on focus....",
trigger = "hover")
),
mainPanel(
)
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
I have also attached a zip .mkv 20 seconds screen recording when you can see a reproducible live example:
REC 2018-04-16-150608.zip
Once the cursor is not hovering anymore the SelectInput widget, I would like to tooltip do be hidden.
Thank you for your help, Dylan
Following @sctyner's question about nesting an accordion-sidebar, I think there may be a way to do this by generalizing the technique.
I am reasonably sure that I understand what she was asking, in terms of arranging the elements - let me try to describe:
Let us think first of only the sidebar panel, which would behave as a "traditional" accordion. The first challenge is to make sure that we can nest accordions. This should be straightforward to test using the existing bs_accordion()
family.
Let us think now of the main panel. In the main panel, we want to display only the elements associated with the displayed (open) elements in the sidebar panel.
When bs_attach_collapse()
is called on a button with custom additional classes, e.g.:
bs_button("She Loves You", class = "collbtn collapsed")
## <button class="btn btn-default collbtn collapsed">She Loves You</button>
such classes are lost:
bs_button("She Loves You", class = "collbtn collapsed") %>%
bs_attach_collapse("yeah")
## <button class="btn btn-default" data-toggle="collapse" data-target="#yeah">She Loves You</button>
This can be a limitation when one wants to use styles to customize how the button looks like when the corresponding panel is collapsed / expanded, which is also the reason behind the example above.
See the attached example Shiny app bs_attach_collapse_custom-class.R, where the classes were added back using tagAppendAttributes()
as a workaround.
Right now, the button_type argument to bs_button only supports default/primary/success/info/warning/danger. It would be nice if it also supported size information.
I am using R Markdown to create a report using R chunks.
When loading bsplus
package and mtcars
dataset, I try to create an accordion. Here is the example:
head <- head(mtcars)
tail <- tail(mtcars)
bs_accordion(id ="Data: mtcars") %>%
bs_append(title = "Head of mtcars", content = head) %>%
bs_append(title = "Tail of mtcars", content = tail)
I would like the accordion to display the objects head
and tail
, which represent datasets for the first 6 rows and last 6 rows of the mtcars
dataset respectively.
However, I get this result:
As you can see, only one text line is shown. So my question is:
How can I show R objects, as data frames, matrix, PCA analysis, plots, etc, in this bsplus
functions?
This problem happens as well with bs_collapse
, bs_accordion
and bs_append
.
Hi,
Great package!
I was wondering if you have any examples on how to annotate the columns in a datatable (https://rstudio.github.io/DT/) with help text similar to your input help documentation.
It would be really useful to be able to put a more detailed column definition with a modal or tool tip.
Thanks,
Iain
embed_vimeo()
in favor of vembedrWould it be possible to create a carousel of images within an .Rmd document obtaining a self-contained .html document?
Thank you for a great job on this package!
Any way of adding this as a feature so that if an image in carousel was clicked it would open a url in browser
We got a carousel, but only the first plot is being displayed.The other slides are blank. Wondering if any one can help to solve this.
https://revathy.shinyapps.io/test/
The reproducible code with error is
## app.R ##
require("shiny")
require("shinydashboard")
require("bsplus")
options(encoding = 'UTF-8')
## ui ##
header <- dashboardHeader(
title = "mooKIT Analytics"
#dropdownMenuOutput("messageMenu")
)
sidebar <- dashboardSidebar(
sidebarMenu(id="menu",
menuItem("Interaction", tabName = "engagement", icon = icon("bullseye"), selected = T)
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName = "engagement",
fluidRow(
tabBox(id="", width=12,
tabPanel(icon = icon('link'), "Network",
uiOutput("ex1")
)
)
)
)
)
)
ui <- dashboardPage(header, sidebar, body)
## server ##
server <- function(input, output, session) {
set.seed(122)
histdata <- rnorm(500)
observe({
output$ex1 <- renderUI({
plot_output_list <- lapply(1:4, function(i) {
plotname <- paste("forumSNGweek", i, sep="")
box(plotOutput(plotname), height = 280, width = 250)
})
#box(sigmaOutput("forumSNG2",width = "98%",height = "630px"), width = 14, height = "650px")
plotters <- bs_carousel(id = "carousel", use_indicators = TRUE)
Reduce(bs_append, plot_output_list, init=plotters)
})
for(i in 1:4) {
plotname <- paste("forumSNGweek", i, sep="")
output[[plotname]] <- renderPlot({
data <- histdata[seq_len(50)]
hist(data)
})
}
})
}
## Run App ##
shinyApp(ui, server)
rather than injecting an attribute into each label element
I think that shiny::navbarPage()
can be exploited here (may be worth an email to Joe when the time comes).
We want to be able to add the header programatically. Maybe a syntax like this:
Let's say that navbar
, dropdown
, and item
are made to be S3 objects.
# need a function to generate relative path given two normalized paths
dropdown_foo <-
dropdown(title = "foo") %>%
add(item(title = "intro to foo", link = "...")) %>%
add(item_sep()) %>%
add(item(title = "advanced foo", link = "..."))
navbar <-
compose_navbar(title = "brand stuff", ...) %>%
add(dropdown_foo) %>%
add(dropdown_bar)
The purpose of this family of functions is to allow you to embed help links into shinyInput labels and panel headers. One challenge is that the thing is called label for shinyInputs, and heading for panels.
Maybe bs_label_embed()
could be an alias to bs_heading_embed()
I think that Shiny has some sort of way to help ensure uniqueness of generated id's (must try to remember to ask Joe). If that is the case, then the id argument to a lot of these functions can become non-mandatory.
In this case, it might be helpful to provide an id accessor function so that you can do something like this:
my_collapse <-
collapse() %>%
collapse_append(tags$div(class = "well", "Yeah Yeah Yeah"))
tags$button("She Loves You") %>%
attach_collapse(id(my_collapse))
my_collpase
will help the examples work
If I create a simple accordion like this:
library(shiny)
ui <- fluidPage(
bs_accordion("foo") %>%
bs_append("bar", "hello world")
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
I get an accordion with the default gray look and only the title text is clickable.
But if I simply add bs_set_opts()
in the mix, then the look changes to blue and the entire header is clickable (because of the default params).
I think it's very unintuitive that simply calling the set options function without providing any options results in vastly different options than not using it at all.
The purposes of the bsplus package:
The fact that there is more than one item on this list suggests that this should be more than one package, I hope that I will be forgiven for keeping them together at this nascent stage.
It may be useful to prepend all the functions with bs_
, to keep the namespace clean.
bs_noun()
We are creating a thing.bs_noun_verb(thing, ...)
We are taking an action on the thing
.bs_noun1_verb_noun2(thing1, thing2)
We are taking an action on thing1
using thing2
.If we have an S3 class, then:
bs_verb(thing, ...)
We are taking an action on the thing
.bs_verb_noun(thing1, thing2)
We are taking an action on thing1
using thing2
.bs_append(tag, ...)
we are appending something to the tag, perhaps a panel into a panel-group, or a set of attributes.bs_attach(tag, ...)
we are attaching something to the tagbs_emded(tag, ...)
we are embed something as part of the tagbs_set_opts(tag, ...)
we are setting some options for the tags yet to be appendedLet's consider the differences betweenappend
, attach
, and embed
.
Going back-and-forth a lot in my head as to the extent to which these functions should use the S3 framework.
bs_set_data(tag, ...)
bs_set_aria(tag, ...)
for the each of the named ...
args
data-
or aria-
"true"
and "false"
Note we have to go around the htmltools API to set (rather than append) the attributes - this will need to be addressed.
For the first pass of this package, it is proposed to provide access to some useful components not already offered in Shiny:
We also propose a compound component:
bs_collapse(id, content)
bs_attach_collapse(tag, id_collapse)
tags$button("Click me") %>%
bs_attach_collapse(id_collapse = "ex_collapse")
bs_collapse(id = "ex_collapse", content = tags$p("Hi there"))
S3 class
bs_accordion(id)
bs_append(tag_accordion, title, content)
bs_set_opts(tag_accordion, panel_type, use_heading_link) # boostrap type: "default", "primary", etc.
bs_accordion(id = "meet_the_beatles") %>%
bs_append(title = "John", content = tags$p("Rhythm guitar, vocals")) %>%
bs_append(title = "Paul", content = tags$p("Bass guitar, vocals")) %>%
bs_append(title = "George", content = tags$p("Lead guitar, vocals")) %>%
bs_append(title = "Ringo", content = tags$p("Drums, vocals"))
bs_accordion(id = "with_the_beatles") %>%
bs_set_opts(panel_type = "primary") %>%
bs_append(title = "John", content = tags$p("Rhythm guitar, vocals")) %>%
bs_append(title = "Paul", content = tags$p("Bass guitar, vocals")) %>%
bs_append(title = "George", content = tags$p("Lead guitar, vocals")) %>%
bs_set_opts(panel_type = "info") %>%
bs_append(title = "Ringo", content = tags$p("Drums, vocals"))
bs_modal(id, title, content, footer, size)
bs_attach_modal(tag, id_modal)
Need to think this through
bs_modal_closebutton(title = "Close")
bs_embed_modalhelp(tag_shinyinput, id_modal)
# bs_modal_helplink(id_modal)
# bs_embed_helplink(tag_shinyinput, tag_link)
bs_modal(
id = "help"
title = "I need somebody"
content = tagList(
tags$h4("Help!"),
tags$p("Not just anybody")
),
footer = bs_modal_closebutton(title = "Close")
)
tags$button("Help!") %>%
bs_attach_modal(id_modal = "help")
selectInput(
inputId = "beatles_for_sale",
label = "Choose a Beatle",
choices = c("John", "Paul", "George", "Ringo")
) %>%
bs_embed_modalhelp(id_modal = "help")
bs_embed_tooltip(tag, title)
tags$button("John Lennon") %>%
bs_embed_tooltip(title = "Rhythm Guitar, vocals")
bs_embed_popover(tag, title, content)
tags$button("John Lennon") %>%
bs_embed_popover(
title = "More information",
content = "Although he wrote \"I Am the Walrus\", he later insisted that the Walrus was Paul."
)
S3 Class
bs_carousel(id, use_indicators, use_controls)
bs_append(carousel, content, caption)
bs_append_img(carousel, src, alt, caption)
bs_carousel_caption(title, content) #helper
bs_carousel("the_beatles") %>%
bs_append_img(
src = "img/john.jpg", alt = "John Lennon",
caption = carousel_caption("John Lennon", "Rhythm guitar, vocals")
) %>%
bs_append_img(
src = "img/paul.jpg", alt = "Paul McCartney",
caption = carousel_caption("Paul McCartney", "Bass guitar, vocals")
) %>%
bs_append_img(
src = "img/george.jpg", alt = "George Harrison",
caption = carousel_caption("George Harrison", "Lead guitar, vocals")
) %>%
bs_append_img(
src = "img/ringo.jpg", alt = "Ringo Starr",
caption = carousel_caption("Ringo Starr", "Drums, vocals")
)
This is an add-on that makes it easier to fit more stuff into a shiny app. S3 class
bs_accordion_sidebar(id, spec_side = c(width = 4, offset =0), spec_main = c(width = 8, offset = 0), position = "left")
bs_append(accordion_sidebar, title_side, content_side, content_main)
bs_set_opts(accordion_sidebar, panel_type_active, panel_type_inactive, use_main_panel)
The default behaviour on bs_accordian is to expand the top accordion element.
E.g., bs_accordion(id = "meet_the_beatles") %>%
bs_append(title = "John Lennon", content = "Rhythm guitar, vocals") %>%
bs_append(title = "Paul McCartney", content = "Bass guitar, vocals")
will leave John Lennon expanded. I would rather have all panels collapsed. Is it possible to change the default behaviour to collapsed, or even add a parameter to bs_append to have collapsed/expanded?
Happy to pull and change:)
Will need to change class="panel-collapse collapse in" to class="panel-collapse collapse" for top panel
for example, read_delim
Could be a little more forgiving if we accept seconds(1)
as well as dseconds(1)
FROM
bs_modal(
id = "modal_markdown",
title = "Using Markdown",
body = render_html_fragment(
system.file("markdown", "modal.md", package = "bsplus"),
quiet = TRUE
)
)
TO
bs_modal(
id = "modal_markdown",
title = "Using Markdown",
body = includeMarkdown(system.file("markdown", "modal.md", package = "bsplus"))
)
as per bs doscs the delay attribute should accept:
delay: { "show": 500, "hide": 100 }
However trying the R equivalent failed(i.e. get ignored) while passing a single a number (hence applied to both show and hide works). Not sure If I am doing anything wrong with the syntax but JSONifying my argument looks file:
> toJSON(list("show" = 500, "hide" = 100), auto_unbox = T)
{"show":500,"hide":100}
How do I apply different number to show and hide parameters please?
Reproducible example (delay argument has no impact):
library(shiny)
library(bsplus)
library(shinyWidgets)
ui <- fluidPage(
use_bs_tooltip(), # you need to call this function somewhere in your ui
titlePanel("Hello Shiny!"),
sidebarLayout(
sidebarPanel(
shinyWidgets::materialSwitch(inputId = "testBS", label = "Test BS") %>%
bs_embed_tooltip(title = "this one is not okay!",
trigger = "hover", delay = list("show" = 3500, "hide" = 50))
),
mainPanel(
)
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
While single number works fine:
library(shiny)
library(bsplus)
library(shinyWidgets)
ui <- fluidPage(
use_bs_tooltip(), # you need to call this function somewhere in your ui
titlePanel("Hello Shiny!"),
sidebarLayout(
sidebarPanel(
shinyWidgets::materialSwitch(inputId = "testBS", label = "Test BS") %>%
bs_embed_tooltip(title = "this one is okay!",
trigger = "hover", delay = 2500)
),
mainPanel(
)
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
could be useful for accordion-sidebars
CRAN, apparently, does not like boostrap
http://getbootstrap.com/components/
We have button_type
, panel_type
, ... all referring to the Bootstrap type.
Maybe change them all to bs_type
?
How to make them work with shinydashboards.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.