rstudio / flexdashboard

Easy interactive dashboards for R
https://pkgs.rstudio.com/flexdashboard/
Other
816 stars 301 forks source link

Inlined script tags never run in runtime:shiny documents #29

Closed daattali closed 8 years ago

daattali commented 8 years ago

When using runtime:shiny together with flex dashboard, is it possible to call JavaScript functions using the session$sendCustomMessage() system? I tried the following simple code and it seemed to work in a regular rmarkdown doc with Shiny, but when I add the flexdashboard output it doesn't work anymore.

tags$script("Shiny.addCustomMessageHandler('mymsg', function(msg){ alert(msg); })")
textInput("text", "Message", "hello")
actionButton("submit", "Submit")

observeEvent(input$submit, {
  session$sendCustomMessage('mymsg', input$text)
})

I also noticed that the usual "knit" button that changes to "Run document" when using runtime:shiny changes back to "knit" when using dashflexboard.

jjallaire commented 8 years ago

The "Knit" button issue is resolved in the RStudio Preview Release (https://www.rstudio.com/products/rstudio/download/preview/)

I don't think there is a session object in runtime: shiny. You can however do this:

session <- getDefaultReactiveDomain()

@jcheng5 Is this something we should be doing automatically in runtime: shiny (populating the session implicitly just like we populate input and output)

daattali commented 8 years ago

I also didn't think session object exists, but the code above does work as long as the runtime is shiny. It's only when I use flexdashboard that it breaks

jjallaire commented 8 years ago

There must be some load timing issue then. @jcheng5 could you take a look?

On Mon, May 23, 2016 at 6:31 AM, Dean Attali notifications@github.com wrote:

When using runtime:shiny together with flex dashboard, is it possible to call JavaScript functions using the session$sendCustomMessage() system? I tried the following simple code and it seemed to work in a regular rmarkdown doc with Shiny, but when I add the flexdashboard output it doesn't work anymore.

tags$script("Shiny.addCustomMessageHandler('mymsg', function(msg){ alert(msg); })") textInput("text", "Message", "hello") actionButton("submit", "Submit")

observeEvent(input$submit, { session$sendCustomMessage('mymsg', input$text) })

I also noticed that the usual "knit" button that changes to "Run document" when using runtime:shiny changes back to "knit" when using dashflexboard.

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/rstudio/flexdashboard/issues/29

jcheng5 commented 8 years ago

@daattali Do you see any errors in the JS console? If you run it with options(shiny.trace=TRUE) do you see the message being sent to the client?

daattali commented 8 years ago

No errors in the JS console. Using the shiny trace option doesn't show anything in both cases (in a regular rmd shiny doc where session does work I also don't see the messages)

bridgeportbyron commented 8 years ago

@jcheng5 Joe, @jjallaire JJ any update on the status of this issue ?

daattali commented 8 years ago

Any leads yet into why calling session$sendCustomMessage() with flexdashboard doesn't work? I've had several people ask me why shinyjs isn't working for them

daattali commented 8 years ago

I did some embarrassingly low-tech debugging and found out that calling the layoutDashboardPage() function in JavaScript is probably what causes this.

https://github.com/cran/flexdashboard/blob/bfafe15f99c5689164cf5cff23ccef27ab8c5fac/inst/rmarkdown/templates/flex_dashboard/resources/flexdashboard.js#L338

If I return immediately from the body of that function, then this bug is not seen. I have no idea what's going on in that JS function, but hopefully this is useful enough info

jjallaire commented 8 years ago

Unfortunately the layoutDashboardPage function is pretty much the top of the stack in flexdashboard so that doesn't narrow it down much!

There are several shiny-specific issues that have been logged here which I'm not qualified to investigate. In the next couple of weeks I'm going to filter/organize them a bit and then see if we can get the shiny team to take a look at.

On Sun, Jul 17, 2016 at 3:29 AM, Dean Attali notifications@github.com wrote:

I did some embarrassingly low-tech debugging and found out that calling the layoutDashboardPage() function in JavaScript is probably what causes this.

https://github.com/cran/flexdashboard/blob/bfafe15f99c5689164cf5cff23ccef27ab8c5fac/inst/rmarkdown/templates/flex_dashboard/resources/flexdashboard.js#L338

If I return immediately from the body of that function, then this bug is not seen. I have no idea what's going on in that JS function, but hopefully this is useful enough info

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rstudio/flexdashboard/issues/29#issuecomment-233169432, or mute the thread https://github.com/notifications/unsubscribe-auth/AAGXx4-ciqqz6dII3k27wkyxYCsn_u1Iks5qWdnggaJpZM4IkZAm .

daattali commented 8 years ago

Thanks JJ. I was really hoping this info was useful..... If it's any help, the very second line in that function seems to already cause this bug.

jjallaire commented 8 years ago

Great, thanks. We'll take a look! On Sun, Jul 17, 2016 at 6:13 PM Dean Attali notifications@github.com wrote:

Thanks JJ. I was really hoping this info was useful..... If it's any help, the very second line https://github.com/cran/flexdashboard/blob/bfafe15f99c5689164cf5cff23ccef27ab8c5fac/inst/rmarkdown/templates/flex_dashboard/resources/flexdashboard.js#L344 in that function seems to already cause this bug.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rstudio/flexdashboard/issues/29#issuecomment-233207275, or mute the thread https://github.com/notifications/unsubscribe-auth/AAGXx2DaiOaUIqq_wdzarQ64_btXRqRDks5qWqkNgaJpZM4IkZAm .

jcheng5 commented 8 years ago

@jjallaire: I've figured out the problem, and it's basically that any script tags no matter how they're inserted, will be ignored, but only if runtime:shiny.

FlexDashboard.init kicks off the code that eventually calls layoutDashboardPage, which calls jQuery's wrap() and wrapInner() functions in a bunch of places. If the DOM fragments that are being wrapped contain <script> tags, and those script tags haven't actually run yet, then wrapping them will prevent them from ever running. (By design, see https://bugs.jquery.com/ticket/10470)

The problem appears to be that FlexDashboard.init is part of a script tag that's before all of the other script tags, because pandoc_include_args(before_body = dashboardScriptFile) in flex_dashboard.R. So either that before_body needs to become after_body, or better yet, introduce a second dashboardScriptFile after the body just for the script tag that initializes the flexdashboard.

This problem only exists on runtime:shiny because you're invoking Flexdashboard.init inside of a $(document).ready(...), and when Shiny's not involved, this causes the Flexdashboard.init call to be deferred until everything else has had a chance to execute. But when runtime:shiny, this $(document).ready(...) call is not invoked until long after the initial page load (since the entire rmarkdown knitting process happens inside of a uiOutput), so the document's already ready; and in that case, $(document).ready(...) executes the callback before it even returns (as opposed to on next tick, as you might reasonably expect).

jjallaire commented 8 years ago

Fixed via https://github.com/rstudio/flexdashboard/issues/77

daattali commented 8 years ago

Thanks for figuring this one out @jcheng5 and @jjallaire -- I can confirm a bunch of issues have now been fixed by this :)