[英]uiOutput ignores <head> or <script> tag
I am trying to include an Outdooractive(.com) map in my Shiny app via Outdooractive's API, which uses an html page with a script tag in the header and a JavaScript tag in the body.我正在尝试通过 Outdooractive 的 API 在我的 Shiny 应用程序中包含一个 Outdooractive(.com) 地图,该应用程序使用一个 html 页面,在标题中带有一个脚本标签,在正文中使用一个 JavaScript 标签。
When using Outdooractive's html template, saving it as an html file and then including it in a Shiny App via includeHTML("originalFile.html")
, the map is displayed correctly.使用 Outdooractive 的 html 模板,将其保存为 html 文件,然后通过includeHTML("originalFile.html")
将其包含在 Shiny App 中时,地图显示正确。 However, since I want the coordinates for the map to be interactive (without saving it to file in-between), I tried to create the html in a renderUI
using shiny tags, and display it via uiOutput
.但是,由于我希望地图的坐标是交互式的(不将其保存到中间的文件中),我尝试使用闪亮的标签在renderUI
创建 html,并通过uiOutput
显示它。 When doing so, the JavaScript part does not seem to be processed at all.这样做时,JavaScript 部分似乎根本没有被处理。 The header above the map is shown, as is the text below it, but the map is ignored without error message.显示地图上方的标题及其下方的文本,但地图被忽略且没有错误消息。 Interestingly, the same happens when I replace the tag tags$head
by tags$header
.有趣的是,当我用tags$header
替换标签tags$head
, tags$header
发生同样的情况。
Here is my app.R
:这是我的app.R
:
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Outdooractive Map"),
# Sidebar with a text input for coordinates
sidebarLayout(
sidebarPanel(
textInput ("lng",
"Longitude:",
value = "10.000",
),
textInput("lat",
"Latitude:",
value = "45.555")
),
# Show the map
mainPanel(
#includeHTML("originalFile.html") # This works
textOutput("text"), # This shows the correct longitude/latitude
uiOutput("map") # This seems to ignore the script
)
)
)
# Define server logic required to access API
server <- function(input, output) {
output$map <- renderUI({
lng = input$lng
lat = input$lat
tags$html(
tags$div(
tags$head(tags$title("Test"),
HTML('<meta charset="utf-8">'),
tags$script(
src = '//www.outdooractive.com/alpportal/oa_head.js?proj=api-dev-oa&key=yourtest-outdoora-ctiveapi&lang=en'
),
tags$style(HTML(
'.oax .oax-cluster-marker-cont, .oax-cluster-marker-cont {background-color: red;}'
))),
tags$body(
h2("Outdooractive Routes"),
div(class = 'oax-top-cont'),
tags$script(HTML(paste(
'var conf = {frontendtype: "tour", zoom: 11, center:[ ', lng, ", ", lat, ']}; var fvp = oa.api.flexviewpage( conf );')
)),
HTML('There should be a map on top of me.')
)
),
)
})
output$text <- renderText ({
paste(input$lng, input$lat)
})
}
# Run the application
shinyApp(ui = ui, server = server)
To fully replicate the example, this would be the originalFile.html
(which works when line 23 in app.R
is uncommented):要完全复制该示例,这将是originalFile.html
(当app.R
第 23 app.R
未注释时有效):
<!DOCTYPE html>
<html>
<head>
<title>outdooractive platform - API Template</title>
<meta charset="utf-8">
<!-- load Outdooractive Javascript API -->
<script type="text/javascript"
src="//www.outdooractive.com/alpportal/oa_head.js?proj=api-dev-oa&key=yourtest-outdoora-ctiveapi&lang=en"></script>
<style>
.oax .oax-cluster-marker-cont, .oax-cluster-marker-cont {
background-color: red;
}
</style>
</head>
<body>
<br>
<br>
<h2>Outdooractive Routes</h2>
<!-- container used by FlexView API -->
<div class="oax-top-cont"></div>
<!-- and some lines of javascript inside a script tag -->
<script type="text/javascript">
var conf = {
frontendtype: "tour", // choose content type
zoom: 11, // set initial zoom level
center: [ 10.292, 47.546 ] // set initial map center
};
var fvp = oa.api.flexviewpage( conf );
</script>
</body>
</html>
Any pointers would be much appreciated.任何指针将不胜感激。
I would rather call some JavaScript
in an observer:我宁愿在观察者中调用一些JavaScript
:
library(shiny)
library(shinyjs)
library(glue)
# Define UI for application that draws a histogram
ui <- fluidPage(
useShinyjs(),
includeHTML("header.html"), ## see comment
titlePanel("Outdooractive Map"),
sidebarLayout(
sidebarPanel(
textInput ("lng",
"Longitude:",
value = "10.000",
),
textInput("lat",
"Latitude:",
value = "45.555")
),
mainPanel(
div(
class = "oax-top-cont"
)
)
)
)
server <- function(input, output) {
observe({
script <- glue("var conf = {{",
"frontendtype: 'tour',",
"zoom: 11,",
"center: [{input$lng}, {input$lat}]",
"}};",
"var fvp = oa.api.flexviewpage(conf);"
)
runjs(script)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Some remarks:一些备注:
shinyjs
makes using JavaScript
in R
a piece of cake. shinyjs
的使用使得在R
使用JavaScript
变得shinyjs
。 You need to call useShinyjs
somewhere in your UI
and then you can issue arbitrary JS
code via runjs
.您需要在UI
某处调用useShinyjs
,然后您可以通过runjs
发出任意JS
代码。JS
function whenever lat
and/or lng
change and moved the static part (ie the loading of the API and the css
to the UI.我使用观察者,每当lat
和/或lng
更改并移动静态部分(即 API 和css
到 UI 的加载)时,它都会调用相应的JS
函数。UI
instead of includeHTML
:最初,我在UI
使用了以下代码段而不是includeHTML
:tags$head(
tags$script(
type = "text/javascript",
src = "//www.outdooractive.com/alpportal/oa_head.js?proj=api-dev-oa&key=yourtest-outdoora-ctiveapi&lang=en"
),
tags$style(...)
)
JS
from outdooractive and I got response code 403
(forbidden), ie outdoor denied my request.但是,这无法从outdooractive 加载JS
,我收到响应代码403
(禁止),即outdoor 拒绝了我的请求。 My guess is that this is due to using the test account.我的猜测是这是由于使用了测试帐户。 For whatever funny reason hardcoding that bit in a html file and using includeHTML
seems to work (again I can simply guess, but I assume that outdooractive tries somehow to figure out whether you are using the test account just locally or already in production. And maybe the tags$script
part fails this test, while the static approach passes this test, but this is just a pure guess from my side - more importantly includeHTML
workaround works. But you should try to replace the keys by your own ones and see whether you still need the includeHTML
part or you can directly use tags$script in your
UI`):无论出于什么有趣的原因,在 html 文件中硬编码该位并使用includeHTML
似乎都有效(我再次可以简单猜测,但我假设 Outdooractive 尝试以某种方式确定您是在本地使用还是已经在生产中使用测试帐户。也许tags$script
部分未通过此测试,而静态方法通过此测试,但这只是我的纯猜测 - 更重要的是includeHTML
解决方法有效。但是您应该尝试用自己的键替换键,看看您是否仍然需要includeHTML
部分,或者您可以直接tags$script in your
UI 中使用tags$script in your
script`):<script type="text/javascript"
src="//www.outdooractive.com/alpportal/oa_head.js?proj=api-dev-oa&key=yourtest-outdoora-ctiveapi&lang=en">
</script>
<style>
.oax .oax-cluster-marker-cont, .oax-cluster-marker-cont {
background-color: red;
}
</style>
I add a gif of how the app look here in Chrome:我添加了该应用在 Chrome 中的外观的 gif:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.