New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shinyBS not compatible with new shiny (development version 0.13) #62

Open
zross opened this Issue Feb 4, 2016 · 7 comments

Comments

Projects
None yet
3 participants
@zross

zross commented Feb 4, 2016

I updated to the newest Shiny and I'm seeing that the modals etc are not working anymore. I tested out an example on the shinyBS page and it does not seem to work:

library(shiny)
library(shinyBS)

shinyApp(
  ui =
    fluidPage(
      sidebarLayout(
        sidebarPanel(
          sliderInput("bins",
                      "Number of bins:",
                      min = 1,
                      max = 50,
                      value = 30),
          actionButton("tabBut", "View Table")
        ),

        mainPanel(
          plotOutput("distPlot"),
          bsModal("modalExample", "Data Table", "tabBut", size = "large",
                  dataTableOutput("distTable"))
        )
      )
    ),
  server =
    function(input, output, session) {



      tags$script(src="shinyBS.js")
      tags$head(tags$link(rel="stylesheet", type="text/css",href="shinyBS.css"))

      output$distPlot <- renderPlot({

        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(x, breaks = bins, col = 'darkgray', border = 'white')

      })

      output$distTable <- renderDataTable({

        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        tab <- hist(x, breaks = bins, plot = FALSE)
        tab$breaks <- sapply(seq(length(tab$breaks) - 1), function(i) {
          paste0(signif(tab$breaks[i], 3), "-", signif(tab$breaks[i+1], 3))
        })
        tab <- as.data.frame(do.call(cbind, tab))
        colnames(tab) <- c("Bins", "Counts", "Density")
        return(tab[, 1:3])

      }, options = list(pageLength=10))

    }
)
@leonawicz

This comment has been minimized.

Show comment
Hide comment
@leonawicz

leonawicz Feb 9, 2016

I am also having trouble with bsModal, entire screen gray, including modal. I can hack it to work locally/in RStudio only (in my app at least, it seems to conflict with the shinythemes package, using theme=shinytheme("themename") in a navbarPage.).

If I set the modal-backdrop z-index to 1000 in a custom css file it then works.

If I remove shinythemes, even then saying theme="string" where string is a link to the exact same bootswatch theme, it then works.

However, the hacks are ultimately no good because even with them modals will not work when run on shiny server, either a local server instance or on shinyapps.io, which unfortunately I am unable to troubleshoot.

leonawicz commented Feb 9, 2016

I am also having trouble with bsModal, entire screen gray, including modal. I can hack it to work locally/in RStudio only (in my app at least, it seems to conflict with the shinythemes package, using theme=shinytheme("themename") in a navbarPage.).

If I set the modal-backdrop z-index to 1000 in a custom css file it then works.

If I remove shinythemes, even then saying theme="string" where string is a link to the exact same bootswatch theme, it then works.

However, the hacks are ultimately no good because even with them modals will not work when run on shiny server, either a local server instance or on shinyapps.io, which unfortunately I am unable to troubleshoot.

@leonawicz

This comment has been minimized.

Show comment
Hide comment
@leonawicz

leonawicz Feb 9, 2016

I can confirm the above example works locally.

R version 3.2.3 (2015-12-10) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] shinyBS_0.61 shiny_0.13.0

loaded via a namespace (and not attached):
[1] R6_2.1.2 tools_3.2.3 htmltools_0.3 Rcpp_0.12.3
[5] jsonlite_0.9.19 digest_0.6.9 xtable_1.8-2 httpuv_1.3.3
[9] mime_0.4

It also works under R 3.2.2.

I'm not sure what type of problem you were having but I cannot reproduce it from the example.

Regarding my problem, I appear to have solved it. The modal was only working in the RStudio browser, but not in Firefox or Chrome. However, this was because I had the call to bsModal in ui.R nested within a div container created by another UI widget, which must have had a fixed or relative positioning that was conflicting with the modal.

leonawicz commented Feb 9, 2016

I can confirm the above example works locally.

R version 3.2.3 (2015-12-10) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] shinyBS_0.61 shiny_0.13.0

loaded via a namespace (and not attached):
[1] R6_2.1.2 tools_3.2.3 htmltools_0.3 Rcpp_0.12.3
[5] jsonlite_0.9.19 digest_0.6.9 xtable_1.8-2 httpuv_1.3.3
[9] mime_0.4

It also works under R 3.2.2.

I'm not sure what type of problem you were having but I cannot reproduce it from the example.

Regarding my problem, I appear to have solved it. The modal was only working in the RStudio browser, but not in Firefox or Chrome. However, this was because I had the call to bsModal in ui.R nested within a div container created by another UI widget, which must have had a fixed or relative positioning that was conflicting with the modal.

@leonawicz

This comment has been minimized.

Show comment
Hide comment
@leonawicz

leonawicz Feb 9, 2016

Sorry for posting three times. Just to clarify, although I did get my modals to work online as well as offline consistently, they all still require a hack. For example, in the theme argument to navbarPage, I must change:

theme=shinytheme("spacelab")

to

theme="http://bootswatch.com/spacelab/bootstrap.css"

Although this sets the theme identically (so far as I can tell), it allows the modals to work properly. Of course, shinyapps.io ignores the second version and forces me to the default theme on their server, but at least the modals still work.

leonawicz commented Feb 9, 2016

Sorry for posting three times. Just to clarify, although I did get my modals to work online as well as offline consistently, they all still require a hack. For example, in the theme argument to navbarPage, I must change:

theme=shinytheme("spacelab")

to

theme="http://bootswatch.com/spacelab/bootstrap.css"

Although this sets the theme identically (so far as I can tell), it allows the modals to work properly. Of course, shinyapps.io ignores the second version and forces me to the default theme on their server, but at least the modals still work.

@zross

This comment has been minimized.

Show comment
Hide comment
@zross

zross Feb 9, 2016

I appreciate your giving this thought. I worked on a function, patterned after bsModal that seems to work on a mini-app. I have not have a chance to test much, though. You'll notice that it is a little specific to my own needs (the radio buttons, for example) but might help.

bsModal2 <- function(id, trigger, title, body.p, radio.id, downloadbtn.id){
  tags$div(class = "modal fade", id = id, 
           `data-trigger` = trigger, 
           tabindex = "-1",
           role = "dialog",
           tags$div(class="modal-dialog", role="document",
                    tags$div(class="modal-content",        
                             tags$div(class = "modal-header", 
                                      tags$button(Type = "button", class = "close", `data-dismiss` = "modal",  HTML("&times;")), 
                                      tags$h3(title)), 

                             tags$div(class = "modal-body",
                                      tags$p(body.p),
                                      br(),
                                      radioButtons(inputId="filetype1", label='Field separator:',
                                                   choices=c("Comma separated valued" = "csv",
                                                             "Tab separated values" = "tsv")),
                                      downloadButton(outputId = downloadbtn.id, label = "Start")
                             ),
                             tags$div(class = "modal-footer", 
                                      tags$a(href = "#", class = "btn", 
                                             `data-dismiss` = "modal", "Close")
                             )# end modal footer
                    )#end modal content
           )#end modal dialog
  )# end modal fade

}

And then using the function:

mode1 <- bsModal2(id="xx",
          trigger = "btn",
          title = "Download data",
          body.p = "blah, blah",
          radio.id = "filetype1",
          downloadbtn.id = 'btnStartDownloadDisagData_explore')

zross commented Feb 9, 2016

I appreciate your giving this thought. I worked on a function, patterned after bsModal that seems to work on a mini-app. I have not have a chance to test much, though. You'll notice that it is a little specific to my own needs (the radio buttons, for example) but might help.

bsModal2 <- function(id, trigger, title, body.p, radio.id, downloadbtn.id){
  tags$div(class = "modal fade", id = id, 
           `data-trigger` = trigger, 
           tabindex = "-1",
           role = "dialog",
           tags$div(class="modal-dialog", role="document",
                    tags$div(class="modal-content",        
                             tags$div(class = "modal-header", 
                                      tags$button(Type = "button", class = "close", `data-dismiss` = "modal",  HTML("&times;")), 
                                      tags$h3(title)), 

                             tags$div(class = "modal-body",
                                      tags$p(body.p),
                                      br(),
                                      radioButtons(inputId="filetype1", label='Field separator:',
                                                   choices=c("Comma separated valued" = "csv",
                                                             "Tab separated values" = "tsv")),
                                      downloadButton(outputId = downloadbtn.id, label = "Start")
                             ),
                             tags$div(class = "modal-footer", 
                                      tags$a(href = "#", class = "btn", 
                                             `data-dismiss` = "modal", "Close")
                             )# end modal footer
                    )#end modal content
           )#end modal dialog
  )# end modal fade

}

And then using the function:

mode1 <- bsModal2(id="xx",
          trigger = "btn",
          title = "Download data",
          body.p = "blah, blah",
          radio.id = "filetype1",
          downloadbtn.id = 'btnStartDownloadDisagData_explore')
@zross

This comment has been minimized.

Show comment
Hide comment
@zross

zross Feb 9, 2016

This is more general and seems to work in my big app

bsModal2 <- function(id, trigger, title, body.p, radio.id, downloadbtn.id, extratags = NULL){
  tags$div(class = "modal fade", id = id, 
           `data-trigger` = trigger, 
           tabindex = "-1",
           role = "dialog",
           tags$div(class="modal-dialog", role="document",
                    tags$div(class="modal-content",        
                             tags$div(class = "modal-header", 
                                      tags$button(Type = "button", class = "close", `data-dismiss` = "modal",  HTML("&times;")), 
                                      tags$h3(title)), 

                             tags$div(class = "modal-body",
                                      tags$p(body.p),
                                      br(),
                                      if(!is.null(extratags)) eval(parse(text=extratags)),
                                      downloadButton(outputId = downloadbtn.id, label = "Start")
                             ),
                             tags$div(class = "modal-footer", 
                                      tags$a(href = "#", class = "btn", 
                                             `data-dismiss` = "modal", "Close")
                             )# end modal footer
                    )#end modal content
           )#end modal dialog
  )# end modal fade

}


extrainfo<-"radioButtons(inputId='filetype1', label='Field separator:',
             choices=c('Comma separated valued' = 'csv',
                       'Tab separated values' = 'tsv'))"


modal1 <- bsModal2(id="datatableModal_explore",
          trigger = "btnDownloadDisagData_explore",
          title = "Download disaggregated data",
          body.p = "The data in the table will be downloaded as a text file with the values separated
               by a comma or a tab.  Select your preferred field separator and then download the data.
          These can be opened in a text editor, or spreadsheet package.",
          downloadbtn.id = 'btnStartDownloadDisagData_explore',
          extratags = extrainfo)

ui <- fluidPage(
  tags$head(tags$link(rel="stylesheet", type="text/css",href="spacelab.min.css")),
  numericInput(inputId = "n",
               "Sample size", value = 25),
  plotOutput(outputId = "hist"),
  actionButton("btnDownloadDisagData_explore", "Download disaggregated data", 
               class = "btn-primary", `data-toggle`="modal",
               `data-target`="#datatableModal_explore", icon=icon("download")),
    modal1

)

server <- function(input, output) { 
  output$hist <- renderPlot({
    hist(rnorm(input$n))
  })
}
shinyApp(ui = ui, server = server)

zross commented Feb 9, 2016

This is more general and seems to work in my big app

bsModal2 <- function(id, trigger, title, body.p, radio.id, downloadbtn.id, extratags = NULL){
  tags$div(class = "modal fade", id = id, 
           `data-trigger` = trigger, 
           tabindex = "-1",
           role = "dialog",
           tags$div(class="modal-dialog", role="document",
                    tags$div(class="modal-content",        
                             tags$div(class = "modal-header", 
                                      tags$button(Type = "button", class = "close", `data-dismiss` = "modal",  HTML("&times;")), 
                                      tags$h3(title)), 

                             tags$div(class = "modal-body",
                                      tags$p(body.p),
                                      br(),
                                      if(!is.null(extratags)) eval(parse(text=extratags)),
                                      downloadButton(outputId = downloadbtn.id, label = "Start")
                             ),
                             tags$div(class = "modal-footer", 
                                      tags$a(href = "#", class = "btn", 
                                             `data-dismiss` = "modal", "Close")
                             )# end modal footer
                    )#end modal content
           )#end modal dialog
  )# end modal fade

}


extrainfo<-"radioButtons(inputId='filetype1', label='Field separator:',
             choices=c('Comma separated valued' = 'csv',
                       'Tab separated values' = 'tsv'))"


modal1 <- bsModal2(id="datatableModal_explore",
          trigger = "btnDownloadDisagData_explore",
          title = "Download disaggregated data",
          body.p = "The data in the table will be downloaded as a text file with the values separated
               by a comma or a tab.  Select your preferred field separator and then download the data.
          These can be opened in a text editor, or spreadsheet package.",
          downloadbtn.id = 'btnStartDownloadDisagData_explore',
          extratags = extrainfo)

ui <- fluidPage(
  tags$head(tags$link(rel="stylesheet", type="text/css",href="spacelab.min.css")),
  numericInput(inputId = "n",
               "Sample size", value = 25),
  plotOutput(outputId = "hist"),
  actionButton("btnDownloadDisagData_explore", "Download disaggregated data", 
               class = "btn-primary", `data-toggle`="modal",
               `data-target`="#datatableModal_explore", icon=icon("download")),
    modal1

)

server <- function(input, output) { 
  output$hist <- renderPlot({
    hist(rnorm(input$n))
  })
}
shinyApp(ui = ui, server = server)
@zross

This comment has been minimized.

Show comment
Hide comment
@zross

zross Feb 9, 2016

A better version, closer to the original. I'm finding that you need to remember to have the data-toggle and data-target attributes on the associated actionButton.

bsModal_alt <- function(id, title, trigger, ...){
  # id<-'a'
  # trigger <- 'b'
  # title <- 'c'
  # body.p <- 
  mo <- tags$div(class = "modal fade", id = id, 
           `data-trigger` = trigger, 
           tabindex = "-1",
           role = "dialog",
           tags$div(class="modal-dialog", role="document",
                    tags$div(class="modal-content",        
                             tags$div(class = "modal-header", 
                                      tags$button(Type = "button", class = "close", `data-dismiss` = "modal",  HTML("&times;")), 
                                      tags$h3(title)), 

                             tags$div(class = "modal-body"),
                             tags$div(class = "modal-footer", 
                                      tags$a(href = "#", class = "btn", 
                                             `data-dismiss` = "modal", "Close")
                             )# end modal footer
                    )#end modal content
           )#end modal dialog
  )# end modal fade
  mo$children[[1]]$children[[1]]$children[[2]] <- 
    tagAppendChildren(mo$children[[1]]$children[[1]]$children[[2]], list = list(...))
  return(mo)
}



# bsModal_alt("myid", "mytrigger", "mytitle",
#             tags$p("This is a p"), tags$h3("this is h3"))

zross commented Feb 9, 2016

A better version, closer to the original. I'm finding that you need to remember to have the data-toggle and data-target attributes on the associated actionButton.

bsModal_alt <- function(id, title, trigger, ...){
  # id<-'a'
  # trigger <- 'b'
  # title <- 'c'
  # body.p <- 
  mo <- tags$div(class = "modal fade", id = id, 
           `data-trigger` = trigger, 
           tabindex = "-1",
           role = "dialog",
           tags$div(class="modal-dialog", role="document",
                    tags$div(class="modal-content",        
                             tags$div(class = "modal-header", 
                                      tags$button(Type = "button", class = "close", `data-dismiss` = "modal",  HTML("&times;")), 
                                      tags$h3(title)), 

                             tags$div(class = "modal-body"),
                             tags$div(class = "modal-footer", 
                                      tags$a(href = "#", class = "btn", 
                                             `data-dismiss` = "modal", "Close")
                             )# end modal footer
                    )#end modal content
           )#end modal dialog
  )# end modal fade
  mo$children[[1]]$children[[1]]$children[[2]] <- 
    tagAppendChildren(mo$children[[1]]$children[[1]]$children[[2]], list = list(...))
  return(mo)
}



# bsModal_alt("myid", "mytrigger", "mytitle",
#             tags$p("This is a p"), tags$h3("this is h3"))
@markriseley

This comment has been minimized.

Show comment
Hide comment
@markriseley

markriseley May 13, 2016

@leonawicz, @zross I found if you download the bootswatch theme .css file and place it in your app's www folder, it should work even on shinyapps.io with the theme correctly applied and no modifications needed to bsModal eg.

    navbarPage(..., theme = "spacelab.css", ...)

I really couldn't say why shinythemes breaks things, but this appears to fix it even on latest version of shiny and r 3.3.0.

markriseley commented May 13, 2016

@leonawicz, @zross I found if you download the bootswatch theme .css file and place it in your app's www folder, it should work even on shinyapps.io with the theme correctly applied and no modifications needed to bsModal eg.

    navbarPage(..., theme = "spacelab.css", ...)

I really couldn't say why shinythemes breaks things, but this appears to fix it even on latest version of shiny and r 3.3.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment