1

I intend to make a Javascript variable from an iframe available to be readable in Shiny. Following these answers:

-Display HTML file in Shiny App

-How do I print an input from the R shiny UI to the console?

I was able to make the following code:

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(title = 'demo'),
    dashboardSidebar(
      sidebarMenu(
        menuItem('Banco de Dados',
                  tabName = 'banco_de_dados',
                  icon = icon('th'))
      )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = 'banco_de_dados',
        h2('Banco de Dados'),
        textOutput('view'),
        htmlOutput('map')
      )
    )
  )
)

server <- function(input, output, session) {
  output$map <- shiny::renderUI({
    tags$iframe(seamless = 'seamless',
                src = 'foo.html',
                width = 800,
                height = 800)
  })

  clickCounter <- reactive({ input$clickCounter })

  output$view <- renderText(paste0('Click counter is: ', clickCounter()))
}

shinyApp(ui, server)

And the foo.html in my www folder:

<html>
  <script type="text/javascript">
    let clickCounter = 0;
  </script>
  <body>
    TEST
    <button id="myButton" onclick="clickCounter += 1;console.log(clickCounter);">Click here</button>
  </body>
</html>

The big problem right now is that I cannot capture input$sclickCounter value. And as you can see, I can change the variable value in the iframe and display it in my browser's console:

enter image description here

How can I fix this and make my code behave as I expect?

1 Answers1

1

I'm assuming that you are using the iframe for the sole purpose of displaying the html in your shiny app.

If we use includeHTML instead we can use the JS function Shiny.setInputValue to populate the input on the server side:

app.R

library(shiny)
library(shinydashboard)
library(shinyjs)

ui <- dashboardPage(
  dashboardHeader(title = 'demo'),
    dashboardSidebar(
      sidebarMenu(
        menuItem('Banco de Dados',
                  tabName = 'banco_de_dados',
                  icon = icon('th'))
      )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = 'banco_de_dados',
        h2('Banco de Dados'),
        textOutput('view'),
        htmlOutput('map')
      )
    )
  )
)

server <- function(input, output, session) {
  output$map <- shiny::renderUI({
    includeHTML('www/foo.html')
  })
  clickCounter <- reactive({ input$clickCounter })
  output$view <- renderText(paste0('Click counter is: ', clickCounter()))
}

shinyApp(ui, server)

www/foo.html

<html>
  <script type="text/javascript">
    let clickCounterVar = 0;
    Shiny.setInputValue(id = 'clickCounter', value = clickCounterVar);
  </script>
  <body>
    TEST
    <button id = "myButton" onclick = "clickCounterVar += 1; Shiny.setInputValue(id = 'clickCounter', value = clickCounterVar);">Click here</button>
  </body>
</html>

Please see this related article.

ismirsehregal
  • 30,045
  • 5
  • 31
  • 78