Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get attribute of element in rendered UI with JavaScript in Shiny

I am trying to get or change a attribute of a Javascript element in Shiny. So in the example below, I would like to obtain the iframe width directly when it is rendered using Javascript. I know I can set the width of the iframe, but that is not the goal. I would like to be able to get other attributes than width as well, for example the frameBorder attribute of an iframe.

Here it says that "The last event to be fired for x is shiny:value", so I assumed binding to that would work:

library(shiny)

jsCode <- tags$head(tags$script(HTML( "
$(document).on('shiny:value', function(e){
  if (e.target.id === 'my_iframe')
    {
     alert('JS code is running now.');
     console.log(e);
     var iframe = document.getElementById('my_iframe');
     console.log(iframe.width);
    }
})")))

ui <- fluidPage(
  jsCode,
  uiOutput('my_iframe')
)

server <- function(input, output){
  output$my_iframe <- renderUI({
    tags$iframe(src='http://www.example.com/', height=600)
  })
}

shinyApp(ui = ui, server = server)

However, we can see that the alert already fires before the iframe is actually rendered(?) So my question; how can I obtain the width (or any other attribute, such as frameborder, see the image below) of the iframe with Javascript directly when it is rendered?

Thanks in advance for any suggestions.

enter image description here

like image 403
Florian Avatar asked Apr 05 '18 08:04

Florian


1 Answers

I would use the event DOMNodeInserted. As soon as an iframe is added to the DOM, your code will be executed:

$('html').on('DOMNodeInserted', 'iframe', function() {
  alert("Fire in the hole!");
  # Getting and setting CSS properties
  $(this).css('background');                  # get
  $(this).css('background-color', '#330000'); # set

  # Getting elements attributes
  $(this).attr('frameborder');      # get
  $(this).attr('frameborder', '0'); # set
});

Notice that the frameborder attribute is not actively set and therefore our attr() call returns undefined. You still see a frameborder though since it's default value is 1 (turned on).

like image 131
Martin Schmelzer Avatar answered Sep 27 '22 17:09

Martin Schmelzer