I am looking to add a Lattitude / Longitude search widget to a Shiny leaflet map. I found a workable leaflet js solution here , and I would like to port the js function into my R Shiny application. Using the htmlwidgets onRender function with panTo, I can get the map to pan to specific coordinates; however,I want a user to be able to type in lat and long and zoom to that location on the map. Here is the code for a sample map that I have been using to test potential solutions. I have been unsuccessful in my attempts to apply the submitted coordinates to the map. The commented out code in the onRender is one of my attempts.
library(shiny)
library(leaflet)
ui <- fluidPage(leafletOutput("mymap"),
tags$div(
HTML(
'
Latitude: <input type="text" name="lat" id="lat"/>
Longitude: <input type="text" name="lng" id="lng"/>
<input type="button" onclick="zoomTo()" value="zoomTo"/>
'
)
))
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
leaflet() %>%
addProviderTiles(providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)) %>%
setView(15, 47, 12) %>%
htmlwidgets::onRender(
'function(el, x) {
this.panTo(new L.LatLng(26, -80));
#var lat = document.getElementById("lat").value;
#var lng = document.getElementById("lng").value;
#this.panTo(new L.LatLng(lat, lng));
}'
)
})
}
shinyApp(ui, server)
By referring to input$zoomTo
in the renderLeaflet
statement, Shiny re-runs that function if you click the button. To make it work, I had to assign the button an id
and the correct class
.
I am not sure why you use HTML and JavaScript to do all this instead of using the widgets provided by Shiny. Take a look at the Shiny Widget Gallery to see what's possible using just R functionality.
library(shiny)
library(leaflet)
ui <- fluidPage(leafletOutput("mymap"),
tags$div(
HTML(
'
Latitude: <input type="text" name="lat" id="lat"/>
Longitude: <input type="text" name="lng" id="lng"/>
<input id="zoomTo" type="button" value="zoomTo" class="action-button"/>
'
)
))
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
input$zoomTo
leaflet() %>%
addProviderTiles(providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)) %>%
setView(15, 47, 12) %>%
htmlwidgets::onRender(
'function(el, x) {
var lat = document.getElementById("lat").value;
var lng = document.getElementById("lng").value;
this.panTo(new L.LatLng(lat, lng));
}'
)
})
}
shinyApp(ui, server)