Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture click within iframe in a shiny app

I want to capture a click on a link within an iframe in a shiny app. And i want to know which link was clicked.

Outside shiny this works fine. I added a fully reproducible example for a related question: https://stackoverflow.com/a/46093537/3502164 (It has to run on a (local) server, e.g. xaamp).

My attempt:

1) The app to be saved in Path/To/App.

2) In the www folder store the html file that should be displayed within iframe.

fileWithLink.html

<html>
<body>
<a href="https://stackoverflow.com/">SOreadytohelp</a>
</body>
</html>

3) App has to be started with runApp("Path/To/App", launch.browser = TRUE) (So that a local server is started).

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  htmlOutput("filecontainer")
)

server <- function(input, output, session){
  session$onFlushed(once = T, function(){
      runjs("
          console.log('I arrive here')
          $('#filecontainer').load(function(){
            console.log('But not here')  
            var iframe = $('#filecontainer').contents();
            iframe.find('#a').click(function(){
              alert('I want to arrive here');
            });
          });
      ")
  })  

  output$filecontainer <- renderUI({
    tags$iframe(src = "fileWithLink.html", height = 600, width = 1200)
  })
}

shinyApp(ui, server)
like image 269
Tonio Liebrand Avatar asked Sep 07 '17 10:09

Tonio Liebrand


1 Answers

The iframe is enclosed in a div with relevant id ($('#filecontainer iframe')). There is a typo calling the anchor tags. I changed destination to avoid cross scripting issues:

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  htmlOutput("filecontainer")
)

server <- function(input, output, session){
  session$onFlushed(once = T, function(){
    runjs("
          console.log('I arrive here')
          $('#filecontainer iframe').load(function(){
            console.log('But not here')  
            var iframe = $('#filecontainer iframe').contents();
            iframe.find('a').click(function(){
              console.log('am i here')  
              alert('I want to arrive here');
            });
          });
          ")
  })  

  output$filecontainer <- renderUI({
    tags$iframe(src = "fileWithLink.html", height = 600, width = 1200)
  })
  }

shinyApp(ui, server)

fileWithLink.html

<html>
<body>
<a href="anotherpage.html">SOreadytohelp</a>
</body>
</html>

anotherpage.html

<html>
<body>
Another page
</body>
</html>
like image 55
jdharrison Avatar answered Oct 18 '22 20:10

jdharrison