Skip to content
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

When inserting javascript with insertUI, does it have to be wrapped in tags$head()? (Bug or feature?) #1545

Closed
daattali opened this issue Jan 18, 2017 · 4 comments · Fixed by #3630

Comments

@daattali
Copy link
Contributor

daattali commented Jan 18, 2017

Consider this code that adds JS code that simply shows an alert box:

ui <- fluidPage(
  actionButton("go", "Insert javascript with an alert")
)
server <- function(input, output, session) {
  observeEvent(input$go, {
    insertUI(
      selector = "head", where = "beforeEnd", immediate = TRUE,
      tags$script("alert('hello')")
    )
  })
}
shinyApp(ui = ui, server = server)

When you click the button, the javascript is added into the <head> tag of the DOM, but nothing happens.

If you wrap the inserted UI in tags$head(...), then you do get the javascript alert to show up.

I don't know how the tags$head() works - I assumed that it simply inserts into the tag, but that would mean that the original code should also work. I guess there is some extra magic that happens for tags$head() that doesn't happen when I add it manually. Is it correct that JS code (and maybe other resources?) have to be wrapped in tags$head() in order for them to work?

@bborgesr
Copy link
Contributor

bborgesr commented Mar 20, 2017

This seems to be a minor bug. When you use tags$head, this is called. This somehow seems to avoid this problem (script elements inserted using innerHTML do not execute when they are inserted.)

Some reading material, in particular, this example that reproduces the same problem. His solution is pretty hacky (inserting and removing an image so you can use the onload attribute).

@jcheng5
Copy link
Member

jcheng5 commented Mar 20, 2017

We could reimplement insertAdjacentHTML using jquery's after, before, prepend, and append functions.

@daattali
Copy link
Contributor Author

Sometimes I wonder if I'm the only person who runs into this issue bcause once a year I come across this problem, google for a solution, and always end up back in this thread :)

That's a subtle way to ping to see if this would perhaps make it into a future release if the "Effort: Low" label is correct

@cpsievert
Copy link
Collaborator

Sometimes I wonder if I'm the only person who runs into this issue

@daattali not the only one :)

We should probably do what @jcheng5 suggested years ago, but in the meantime, a workaround is to leverage htmlDependency()'s head argument:

ui <- fluidPage(
  actionButton("go", "Insert javascript with an alert")
)
server <- function(input, output, session) {
  observeEvent(input$go, {
    insertUI(
      selector = "head",
      ui = htmltools::htmlDependency(
        name = "fake-dep",
        version = "1.0",
        src = ".", package = "shiny",
        head = "<script>alert('hello')</script>"
      )
    )
  })
}
shinyApp(ui = ui, server = server)

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

Successfully merging a pull request may close this issue.

6 participants