ebailey78 / shinyBS

Twitter Bootstrap Components for Shiny
182 stars 47 forks source link

bsModal doesn't open when trigger is inside renderUI #57

Open bartekch opened 9 years ago

bartekch commented 9 years ago

I've discovered that when trigger for modal is defined not in UI directly, but through uiOutput and renderUI mechanism, it doesn't work. Here the minimal example that isn't working.

library("shiny")
library("shinyBS")

ui <- basicPage(
  bsModal("modal", "foo", trigger = "button", "bar"),
  htmlOutput("button_ui")
)

server = function(input, output, session) {
  output$button_ui <- renderUI({
    actionButton("button", "Show modal")
  })
}

runApp(list(ui = ui, server = server))

I've tried to manually add additional attributes to actionButton:

actionButton("button", "Show modal", 
                "data-toggle" = "modal", "data_target" = "#modal")

but it hasn't changed anything.

Any ideas why it is so?

Here my session info:

R version 3.2.2 (2015-08-14)
Platform: i386-w64-mingw32/i386 (32-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=Polish_Poland.1250  LC_CTYPE=Polish_Poland.1250    LC_MONETARY=Polish_Poland.1250
[4] LC_NUMERIC=C                   LC_TIME=Polish_Poland.1250    

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

other attached packages:
[1] shinyBS_0.62 shiny_0.12.2

loaded via a namespace (and not attached):
 [1] R6_2.1.1         htmltools_0.2.6  tools_3.2.2      rstudioapi_0.3.1 Rcpp_0.12.1.4    jsonlite_0.9.17  digest_0.6.8    
 [8] xtable_1.8-0     httpuv_1.3.3     mime_0.4
shrektan commented 9 years ago

It should work, although I have not checked your code, because I did it in my app.

发自我的 iPhone

在 2015年11月11日,00:00,bartekch notifications@github.com 写道:

I've discovered that when trigger for modal is defined not in UI directly, but through uiOutput and renderUI mechanism, it doesn't work. Here the minimal example that isn't working.

library("shiny") library("shinyBS")

ui <- basicPage( bsModal("modal", "foo", trigger = "button", "bar"), htmlOutput("button_ui") )

server = function(input, output, session) { output$button_ui <- renderUI({ actionButton("button", "Show modal") }) }

runApp(list(ui = ui, server = server)) I've tried to manually add additional attributes to actionButton:

actionButton("internal_button", "Show modal", "data-toggle" = "modal", "data_target" = "#modal") but it hasn't changed anything.

Any ideas why it is so?

Here my session info:

R version 3.2.2 (2015-08-14) Platform: i386-w64-mingw32/i386 (32-bit) Running under: Windows 7 x64 (build 7601) Service Pack 1

locale: [1] LC_COLLATE=Polish_Poland.1250 LC_CTYPE=Polish_Poland.1250 LC_MONETARY=Polish_Poland.1250 [4] LC_NUMERIC=C LC_TIME=Polish_Poland.1250

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

other attached packages: [1] shinyBS_0.62 shiny_0.12.2

loaded via a namespace (and not attached): [1] R6_2.1.1 htmltools_0.2.6 tools_3.2.2 rstudioapi_0.3.1 Rcpp_0.12.1.4 jsonlite_0.9.17 digest_0.6.8
[8] xtable_1.8-0 httpuv_1.3.3 mime_0.4 — Reply to this email directly or view it on GitHub.

bartekch commented 9 years ago

Well, it should, but it doesn't for me. What versions of shiny and shinyBS do you have?

shrektan commented 9 years ago

@bartekch I just checked your code.

Sorry, it's true that it won't work. But, it will work if you write it like this, which is moving the modal to the server part:

library("shiny")
library("shinyBS")

ui <- fluidPage(
  uiOutput("button_ui")
)

server = function(input, output, session) {
  output$button_ui <- renderUI({
    tagList(
      bsModal("modal", "foo", trigger = "a", "bar"),
      actionButton("a", "Show modal")
    )
  })
}

runApp(list(ui = ui, server = server))

I think the problem happens if you generate the bsModal before the trigger component. The reason may be the same as this: https://github.com/daattali/shinyjs/issues/33

If you really need to set the bsModal before the trigger ui has been generated, I think there might be a solution by using shinyjs

bartekch commented 9 years ago

@shrektan thanks for showing this problem to me, I hasn't been aware of this limitation.

Yes, defining modal in the same place as trigger could be solution. However I have quite a lot of modals in my app and I want to define them in separate place (inside renderUI in separate script actually) to avoid mess in my server script, so I'd prefer not to generate modal right next to trigger.

Using shinyjs is also an option, but I could equally well use native toggleModal function from shinyBS:

library("shiny")
library("shinyBS")

ui <- basicPage(
  bsModal("modal", "foo", trigger = "", "bar"),
  htmlOutput("button_ui")
)

server = function(input, output, session) {
  output$button_ui <- renderUI({
    actionButton("button", "Show modal")
  })
  observeEvent(input$button, {
    toggleModal(session, "modal", "open")
  })
}

runApp(list(ui = ui, server = server))

It's a few lines of code more, but it's working no matter where I put modal definition.

Anyway it would be nice to have trigger working even if defined in renderUI, so I'm leaving this issue open. I'd appreciate it very much if @ebailey78 manages to add this feature, because modals would be even easier to use than now, which would be great!