Reading javascript variable into shiny/R on app load

强颜欢笑 提交于 2019-11-27 15:23:25

问题


What I want to do is get the user ID from a wordpress logged-in user when I load a shiny app in an iframe. This variable could then be used to save and modify user-specific data.


I have gotten some of the way by adding the following code to the wordpress page:

<?php global $current_user; 
get_currentuserinfo(); 
$user_name = $current_user->user_login; 
$user_ID = get_current_user_id(); 
?>

And then this to make it a javascript variable:

<script type="text/javascript"> 
var username = <?php echo json_encode($user_name) ?> ; 
var userID = <?php echo json_encode($user_ID) ?> ; 
</script>




Using the example found here I am able to get the variable if I click a div box.

ui.R:

library(shiny)

shinyUI( bootstrapPage(

  # include the js code
  includeScript("get_user_id.js"),

  # a div named mydiv
  tags$div(id="mydiv",
           style="width: 50px; height :50px; left: 100px; top: 100px;
           background-color: gray; position: absolute"),

  # an element for unformatted text
  verbatimTextOutput("results")
))

server.R:

shinyServer(function(input, output, session) {
  output$results = renderPrint({
    input$mydata
  })
})

get_user_id.js:

$(document).ready(function() {
  document.getElementById("mydiv").onclick = function() {
  document.domain = "DOMAIN_NAME_HERE"; 
  var username = parent.username; 
  var userID = parent.userID; 
    Shiny.onInputChange("mydata", userID);
  };
});



Note that the domain name (or IP) is needed because the shiny app loaded in the iframe is on another port than the wordpress page. The iframe should be created by:

<script type="text/javascript"> 
document.domain = "DOMAIN_NAME_HERE"; 
</script> 
<iframe id="example1" style="border: none; width: 100%; height: 500px;" src="APP_URL" height="150" frameborder="0"></iframe>




But what I want is to just get the variable as soon as the app loads so I can use it in the app to save data to a database etc.
I couldn't find any way to do this. I haven't been able to achieves this using ".onload" or several jquery alternatives I have tried. Any hints would be highly appreciated.




EDIT: Also posted here: https://groups.google.com/forum/#!topic/shiny-discuss/3XM2mHuzqRs


回答1:


Erik Westlund was kind enough to provide the following solution.


get_user_id.js:

document.domain = "MYDOMAIN.com"; 

var userIDVariableName = parent.userID; 
var userID = document.getElementById("userID"); 
userID.value = userIDVariableName; 

var usernameVariableName = parent.username; 
var username = document.getElementById("username"); 
username.value = usernameVariableName;

As mentioned above remember to change the domain. And set it in the page loading the iframe.


ui.R:

library(shiny) 

shinyUI( bootstrapPage( 

# Hidden input boxes to save the variable to 
HTML(‘ <input type="text" id="userID" name="userID" style="display: none;"> ‘), 
HTML(‘ <input type="text" id="username" name="username" style="display: none;"> ‘), 


# include the js code 
includeScript("get_user_id.js"), 

# Show the output 
textOutput("view") 
))

Change the path to the script as needed.


server.R:

shinyServer(function(input, output, session) { 



userID <- reactive({ input$userID }) 
username <- reactive({ input$username }) 

output$view <- renderText( paste0( "User ID is: ",userID()," and username is: ",username() ) ) 

})


Add this to the page containing the iframe:

PHP to get the variable from wordpress.

<?php global $current_user; 
get_currentuserinfo(); 
$user_name = $current_user->user_login; 
$user_ID = get_current_user_id(); 
?>

And then this to make it a java variable:

<script type="text/javascript"> 
var username = <?php echo json_encode($user_name) ?> ; 
var userID = <?php echo json_encode($user_ID) ?> ; 
</script>

Set domain and the iframe:

<script type="text/javascript"> 
document.domain = "MYDOMAIN.com"; 
</script> 
<iframe id="example1" style="border: none; width: 100%; height: 500px;" src="PATH_TO_SHINY_APP" width="300" height="150" frameborder="0"></iframe>



回答2:


If you want to call onInputChange as soon as the Shiny app starts then you need to use the following JavaScript code instead of listening for click events.

$(function() {
  setTimeout(function() {
    Shiny.onInputChange("mydata", userID);
  }, 10)
});


来源:https://stackoverflow.com/questions/23715614/reading-javascript-variable-into-shiny-r-on-app-load

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!