GithubHelp home page GithubHelp logo

ijlyttle / bsplus Goto Github PK

View Code? Open in Web Editor NEW
147.0 13.0 23.0 4.02 MB

Shiny and R Markdown addons to Bootstrap 3

Home Page: http://ijlyttle.github.io/bsplus/

License: Other

R 95.19% CSS 0.86% JavaScript 3.94%
r bootstrap3 shiny rmarkdown

bsplus's People

Contributors

ijlyttle avatar pvictor avatar schloerke avatar tamilyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bsplus's Issues

Request: ability to create an accordion that is collapsed initially

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

make htmlwidgets

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):

  • modal
  • tooltip
  • popover
  • carousel

abuse of htmltools

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 attributes
  • tagName() - gets the name of the tag, i.e. "div", "button"

Adding code chunks to accordion

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)?

collapsible shinyInputs

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

How can I create bsplus accordions using apply functions?

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)

Version of R to use

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?

carousel image rendering as broken link

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)

screen shot 2017-01-27 at 10 22 37

Enable Toggle Modal

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.

disabling panels

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:

  • it is closed
  • it disables any link in the title
  • it applies "disabling opacity" to the panel

Note, a panel would have an Id so that server can use the shinyjs::toggleState() function

tools for id's

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

use pkgdown

would also be a good way to refamiliarize self with the package

attempting bs_modal and bs_attach_modal inside renderUI

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?

bs_accordion doesn't work without attaching the bsplus namespace

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)

Tooltip showing on focus state even if trigger is hover only

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

generalize bs_accordion_sidebar()

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.

Custom classes lost with bs_attach_collapse

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.

Support for button sizes

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.

bsplus functions only show text lines and not R outputs

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:

enter image description here

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.

testing

  • tooltips and popovers
  • modal
  • carousel
  • embed shiny

Self-contained carousel images?

Would 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!

bs_carousel_link option

Any way of adding this as a feature so that if an image in carousel was clicked it would open a url in browser

Carousel for dynamic plots

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)

framework to create navbars

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)

consider function bs_heading_embed()

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()

way to handle not wanting to deal with unique id's

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

Suggestion: bs_set_opts() should not have any effect when not given any parameters

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.

Proposal for API

The purposes of the bsplus package:

  1. Provide access to Bootstrap's Javascript components, created by setting attributes of HTML tags.
  2. Provide functions for some compound components.

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.

Grammar

  • 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.

Verbs

  • 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 tag
  • bs_emded(tag, ...) we are embed something as part of the tag
  • bs_set_opts(tag, ...) we are setting some options for the tags yet to be appended

Let's consider the differences betweenappend, attach, and embed.

  • We can append more than one element to a tag, i.e., we would append multiple panel elements to an accordion.
  • We can attach only one thing to a tag. When we are attaching, we attach the id of an element, not the element itself.
  • We can embed only one thing into a tag. i.e., into a given tag, we embed a tooltip or a popover, modifying the attributes and setting a child element.

Note

Going back-and-forth a lot in my head as to the extent to which these functions should use the S3 framework.

Helper function

bs_set_data(tag, ...)
bs_set_aria(tag, ...)

for the each of the named ... args

  • prefixes the names with data- or aria-
  • converts logical values to "true" and "false"
  • converts lubridate durations to milliseconds
  • converts vectors to space-delimited character strings

Note we have to go around the htmltools API to set (rather than append) the attributes - this will need to be addressed.

Components

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:

  • accordion_sidebar

Collapse

bs_collapse(id, content)
bs_attach_collapse(tag, id_collapse)

Example

tags$button("Click me") %>%
  bs_attach_collapse(id_collapse = "ex_collapse")

bs_collapse(id = "ex_collapse", content = tags$p("Hi there")) 

Accordion

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.

Example

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"))

Modal

bs_modal(id, title, content, footer, size)
bs_attach_modal(tag, id_modal)

Helpers

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)

Example

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")

Tooltip

bs_embed_tooltip(tag, title)

Example

tags$button("John Lennon") %>%
  bs_embed_tooltip(title = "Rhythm Guitar, vocals")

Popover

bs_embed_popover(tag, title, content)

Example

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."
  )

Carousel

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

Example

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")
  ) 

Accordion Sidebar

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) 

bs_accordion default behaviour on top 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

bs_modal example simplification?

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"))
)

delay attribute not fully working in bs_embed_tooltip

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.