Javascript Shinydashboard:Google放置自动完成。InvalidValueError:不是HTMLInputElement的实例
我正在尝试将一个Javascript Shinydashboard:Google放置自动完成。InvalidValueError:不是HTMLInputElement的实例,javascript,r,shiny,shinydashboard,google-places,Javascript,R,Shiny,Shinydashboard,Google Places,我正在尝试将一个shinydashboard放在一起,并使用一个googleplaces搜索框作为文本输入。下面的代码运行在一个常规的shiny页面中,但在放入shinydashboard时抛出一个InvalidValueError:不是HTMLInputElement的实例。(见下图) 我不知道为什么它会在一个普通的闪亮的应用程序中工作,但在shinydashboard中却不起作用 错误截图: 最小可复制代码示例: 注意:首先插入您的Google API密钥 library(shiny) l
shinydashboard
放在一起,并使用一个googleplaces搜索框作为文本输入。下面的代码运行在一个常规的shiny
页面中,但在放入shinydashboard
时抛出一个InvalidValueError:不是HTMLInputElement的实例。(见下图)
我不知道为什么它会在一个普通的闪亮的应用程序中工作,但在shinydashboard
中却不起作用
错误截图:
最小可复制代码示例:
注意:首先插入您的Google API密钥
library(shiny)
library(googleway)
library(shinydashboard)
#key <- "MyKey"
#set_key(key = key)
#google_keys()
ui<- shinydashboard::dashboardPage(
dashboardHeader(title = "Look @ Console"),
dashboardSidebar(list(sidebarMenuOutput("sideBar_menu_UI"))),
dashboardBody(
HTML(paste0(" <script>
function initAutocomplete() {
var autocomplete = new google.maps.places.Autocomplete(document.getElementById('my_address'),{types: ['geocode']});
autocomplete.setFields(['address_components', 'formatted_address', 'geometry', 'icon', 'name']);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
var addressPretty = place.formatted_address;
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || ''),
(place.address_components[3] && place.address_components[3].short_name || ''),
(place.address_components[4] && place.address_components[4].short_name || ''),
(place.address_components[5] && place.address_components[5].short_name || ''),
(place.address_components[6] && place.address_components[6].short_name || ''),
(place.address_components[7] && place.address_components[7].short_name || '')
].join(' ');
}
var address_number =''
address_number = [(place.address_components[0] && place.address_components[0].short_name || '')]
var coords = place.geometry.location;
//console.log(address);
Shiny.onInputChange('jsValue', address);
Shiny.onInputChange('jsValueAddressNumber', address_number);
Shiny.onInputChange('jsValuePretty', addressPretty);
Shiny.onInputChange('jsValueCoords', coords);});}
</script>
<script src='https://maps.googleapis.com/maps/api/js?key=", key,"&libraries=places&callback=initAutocomplete' async defer></script>"))
,uiOutput("tabContentUI")
)
)
server <- function(input, output) {
output$sideBar_menu_UI <- renderMenu({
sidebarMenu(id = "sideBar_Menu",
menuItem("Data Import", tabName="datatab", icon = icon("database")),
conditionalPanel("input.sideBar_Menu=='datatab'",
shiny::radioButtons(inputId = "upload_custom_data", label = "Do You Want To Upload Your Own Data?",
choices = c("Yes"=TRUE, "No"=FALSE), selected = FALSE, inline = TRUE),
shiny::uiOutput("conditionalFileInputUI")),
menuItem("AnotherMenu", tabName = "anotherMenu", icon = icon("list-ol")))
})
output$conditionalFileInputUI<- shiny::renderUI({
if(input$upload_custom_data == TRUE){}
if(input$upload_custom_data == FALSE){
list(
shiny::textInput(inputId = "my_address", label = "Search For Address", width = "350px"),
shiny::actionButton(inputId = "add_btn", label = "Add To Dataset", icon = icon("plus"))
)
}
})
### Output$Stuff Here
output$anotherMenu_content<- shiny::renderText({"This is some text" })
output$datatab_content<- shiny::renderUI({ list(shiny::uiOutput("full_address"), shiny::uiOutput("my_map")) })
#### Tab Content UI Materials
output$tabContentUI<- shiny::renderUI({
shinydashboard::tabItems(
shinydashboard::tabItem(tabName = "datatab", shiny::uiOutput("datatab_content")),
shinydashboard::tabItem(tabName = "anotherMenu", shiny::textOutput("anotherMenu_content"))
)
})
my_address <- reactive({
if(!is.null(input$jsValueAddressNumber)){
if(length(grep(pattern = input$jsValueAddressNumber, x = input$jsValuePretty ))==0){
final_address<- c(input$jsValueAddressNumber, input$jsValuePretty)
} else{
final_address<- input$jsValuePretty
}
final_address
}
})
output$full_address <- renderText({
if(!is.null(my_address())){
paste0("The Fuller and Fixed Address is... ", my_address())
}
})
output$my_map <- renderGoogle_map({
my_address <- my_address()
shiny::validate(
need(my_address, "Address not available")
)
gdat <- google_geocode(address = my_address)
my_coords <- geocode_coordinates(gdat)
my_coords <- c(my_coords$lat[1], my_coords$lng[1])
google_map(
location = my_coords,
zoom = 12,
map_type_control = FALSE,
zoom_control = FALSE,
street_view_control = FALSE
)
})
}
shinyApp(ui, server)
更新后的UI现在如下所示:
我能做到这一点的唯一方法是,从server.R
文件中提取侧边栏菜单的所有渲染逻辑,并将其放入ui.R
文件中
最终的工作解决方案是:
library(shiny)
library(googleway)
library(shinydashboard)
#key <- "MyKey"
#set_key(key = mygoogleapikey)
#google_keys()
ui<- shinydashboard::dashboardPage(
dashboardHeader(title = "This Works"),
dashboardSidebar(shinydashboard::sidebarMenu(id="sideBar_Menu",
menuItem("Data Import", tabName="datatab", icon = icon("database")),
conditionalPanel("input.sideBar_Menu=='datatab'",
shiny::radioButtons(inputId = "upload_custom_data", label = "Do You Want To Upload Your Own Data?", choices = c("Yes"=TRUE, "No"=FALSE), selected = TRUE, inline = TRUE),
conditionalPanel("input.upload_custom_data == 'TRUE'",
shiny::actionButton("go", "Go")),
conditionalPanel("input.upload_custom_data == 'FALSE'",
textInput(inputId = "my_address", label = "Type An Address"),
shiny::actionButton(inputId = "add_btn", label = "Add To Dataset", icon = icon("plus")))
), # with outer conditional menu
menuItem("AnotherMenu", tabName = "anotherMenu", icon = icon("list-ol"))
) # with sidebar menu
),
dashboardBody(
HTML(paste0(" <script>
function initAutocomplete() {
var autocomplete = new google.maps.places.Autocomplete(document.getElementById('my_address'),{types: ['geocode']});
autocomplete.setFields(['address_components', 'formatted_address', 'geometry', 'icon', 'name']);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
var addressPretty = place.formatted_address;
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || ''),
(place.address_components[3] && place.address_components[3].short_name || ''),
(place.address_components[4] && place.address_components[4].short_name || ''),
(place.address_components[5] && place.address_components[5].short_name || ''),
(place.address_components[6] && place.address_components[6].short_name || ''),
(place.address_components[7] && place.address_components[7].short_name || '')
].join(' ');
}
var address_number =''
address_number = [(place.address_components[0] && place.address_components[0].short_name || '')]
var coords = place.geometry.location;
//console.log(address);
Shiny.onInputChange('jsValue', address);
Shiny.onInputChange('jsValueAddressNumber', address_number);
Shiny.onInputChange('jsValuePretty', addressPretty);
Shiny.onInputChange('jsValueCoords', coords);});}
</script>
<script src='https://maps.googleapis.com/maps/api/js?key=", key,"&libraries=places&callback=initAutocomplete' async defer></script>"))
,uiOutput("tabContentUI")
)
)
server <- function(input, output) {
### Output$Stuff Here
output$anotherMenu_content<- shiny::renderText({"This is some text" })
output$datatab_content<- shiny::renderUI({ list(shiny::uiOutput("full_address"), shiny::uiOutput("my_map")) })
#### Tab Content UI Materials
output$tabContentUI<- shiny::renderUI({
shinydashboard::tabItems(
shinydashboard::tabItem(tabName = "datatab", shiny::uiOutput("datatab_content")),
shinydashboard::tabItem(tabName = "anotherMenu", shiny::textOutput("anotherMenu_content"))
)
})
my_address <- reactive({
if(!is.null(input$jsValueAddressNumber)){
if(length(grep(pattern = input$jsValueAddressNumber, x = input$jsValuePretty ))==0){
final_address<- c(input$jsValueAddressNumber, input$jsValuePretty)
} else{
final_address<- input$jsValuePretty
}
final_address
}
})
output$full_address <- renderText({
if(!is.null(my_address())){
paste0("The Fuller and Fixed Address is... ", my_address())
}
})
output$my_map <- renderGoogle_map({
my_address <- my_address()
shiny::validate(
need(my_address, "Address not available")
)
gdat <- google_geocode(address = my_address)
my_coords <- geocode_coordinates(gdat)
my_coords <- c(my_coords$lat[1], my_coords$lng[1])
google_map(
location = my_coords,
zoom = 12,
map_type_control = FALSE,
zoom_control = FALSE,
street_view_control = FALSE
)
})
}
shinyApp(ui, server)
库(闪亮)
图书馆(谷歌)
图书馆(shinydashboard)
#钥匙
library(shiny)
library(googleway)
library(shinydashboard)
#key <- "MyKey"
#set_key(key = mygoogleapikey)
#google_keys()
ui<- shinydashboard::dashboardPage(
dashboardHeader(title = "This Works"),
dashboardSidebar(shinydashboard::sidebarMenu(id="sideBar_Menu",
menuItem("Data Import", tabName="datatab", icon = icon("database")),
conditionalPanel("input.sideBar_Menu=='datatab'",
shiny::radioButtons(inputId = "upload_custom_data", label = "Do You Want To Upload Your Own Data?", choices = c("Yes"=TRUE, "No"=FALSE), selected = TRUE, inline = TRUE),
conditionalPanel("input.upload_custom_data == 'TRUE'",
shiny::actionButton("go", "Go")),
conditionalPanel("input.upload_custom_data == 'FALSE'",
textInput(inputId = "my_address", label = "Type An Address"),
shiny::actionButton(inputId = "add_btn", label = "Add To Dataset", icon = icon("plus")))
), # with outer conditional menu
menuItem("AnotherMenu", tabName = "anotherMenu", icon = icon("list-ol"))
) # with sidebar menu
),
dashboardBody(
HTML(paste0(" <script>
function initAutocomplete() {
var autocomplete = new google.maps.places.Autocomplete(document.getElementById('my_address'),{types: ['geocode']});
autocomplete.setFields(['address_components', 'formatted_address', 'geometry', 'icon', 'name']);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
var addressPretty = place.formatted_address;
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || ''),
(place.address_components[3] && place.address_components[3].short_name || ''),
(place.address_components[4] && place.address_components[4].short_name || ''),
(place.address_components[5] && place.address_components[5].short_name || ''),
(place.address_components[6] && place.address_components[6].short_name || ''),
(place.address_components[7] && place.address_components[7].short_name || '')
].join(' ');
}
var address_number =''
address_number = [(place.address_components[0] && place.address_components[0].short_name || '')]
var coords = place.geometry.location;
//console.log(address);
Shiny.onInputChange('jsValue', address);
Shiny.onInputChange('jsValueAddressNumber', address_number);
Shiny.onInputChange('jsValuePretty', addressPretty);
Shiny.onInputChange('jsValueCoords', coords);});}
</script>
<script src='https://maps.googleapis.com/maps/api/js?key=", key,"&libraries=places&callback=initAutocomplete' async defer></script>"))
,uiOutput("tabContentUI")
)
)
server <- function(input, output) {
### Output$Stuff Here
output$anotherMenu_content<- shiny::renderText({"This is some text" })
output$datatab_content<- shiny::renderUI({ list(shiny::uiOutput("full_address"), shiny::uiOutput("my_map")) })
#### Tab Content UI Materials
output$tabContentUI<- shiny::renderUI({
shinydashboard::tabItems(
shinydashboard::tabItem(tabName = "datatab", shiny::uiOutput("datatab_content")),
shinydashboard::tabItem(tabName = "anotherMenu", shiny::textOutput("anotherMenu_content"))
)
})
my_address <- reactive({
if(!is.null(input$jsValueAddressNumber)){
if(length(grep(pattern = input$jsValueAddressNumber, x = input$jsValuePretty ))==0){
final_address<- c(input$jsValueAddressNumber, input$jsValuePretty)
} else{
final_address<- input$jsValuePretty
}
final_address
}
})
output$full_address <- renderText({
if(!is.null(my_address())){
paste0("The Fuller and Fixed Address is... ", my_address())
}
})
output$my_map <- renderGoogle_map({
my_address <- my_address()
shiny::validate(
need(my_address, "Address not available")
)
gdat <- google_geocode(address = my_address)
my_coords <- geocode_coordinates(gdat)
my_coords <- c(my_coords$lat[1], my_coords$lng[1])
google_map(
location = my_coords,
zoom = 12,
map_type_control = FALSE,
zoom_control = FALSE,
street_view_control = FALSE
)
})
}
shinyApp(ui, server)