What is the correct way to use numeric inputs inside a leaflet popup?

leaflet

#1

Alright, so I am stumped. See below for a reproducible R/Shiny/Leaflet example.

If I try to embed a numeric input into a leaflet map, as illustrated below, I am unable to call the value specified in the numeric input. What is the correct way to get a numeric input to work inside a leaflet map in Shiny? I have tried a few things - a. what you see below, b. creating a ui object, c. reactive functions and d. various combinations thereof - but no bananas.

Would really appreciate the help.

library(shiny)
library(leaflet)
library(dplyr)

content <- paste(sep = "<br/>",
             "<b>Change number below:</b>",
             numericInput("numeroUno", label = NULL, value = 1)
)

ui <- fluidPage(
  "This is a map",
  leafletOutput("myMap"),  
  numericInput('numeroDos', label = NULL, value = 5),
  textOutput("mapPopupLink"))

server <- function(input, output, session) {

output$myMap <- renderLeaflet({
 leaflet() %>% 
    setView(lng = 25.0343, lat = 77.3963, zoom = 5) %>% 
    addPopups(-122.327298, 47.597131, content, options = popupOptions(closeButton = FALSE)) %>%
    addTiles() %>%
    addProviderTiles(providers$OpenTopoMap)
  })

 output$mapPopupLink <- renderText({
      paste("The ui-based widget prints: ", input$numeroDos, ". But the server-based widget does not: ", input$numeroUno)
   })
 }
 shinyApp(ui, server)

Let me know if you have any questions…thanks!


#2

I think, I understood your problem (thx, for simple example).

Unfortunately, it looks like the list of map events is limited to clicks, bounds and zoom…

So I think, that for now it is not possible. Crazy things that I’m thinking about is that it probably the environment problem, so if it is possible to create shiny app inside of the leaflet, then internal shiny app could place values to some plase X and external could take it from this place X… But again, it is really crazy.


#3

I see what you’re saying. If you open up my example and look at the app in a browser then look at the source code, it is pretty evident that the working widget (“numeroDos”) is visible, but the one embedded in the leaflet map (“numeroUno”) is no where to be found (see copy/paste below).

Upon further inspection it looks like the function to render the leaflet map in shiny produces the following line:

    <div id="myMap" style="width:100%; height:400px; " class="leaflet html-widget html-widget-output"></div>

In other words, although passing the numeric input into the map is possible, it does not show up in the one-liner that renders the map. It would be my assumption, therefore, that the only way to work around getting a workable numeric input on the map popup would be some sort of JS-based override (for a lack of better words). @jcheng do you have any insight on how I should go about tackling this?


<!DOCTYPE html>
<html>
<head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <script type="application/shiny-singletons"></script>
  <script type="application/html-dependencies">json2[2014.02.04];jquery[1.12.4];shiny[1.0.5];htmlwidgets[0.9];leaflet[0.7.7];leafletfix[1.0.0];leaflet-label[0.2.2];Proj4Leaflet[0.7.2];leaflet-binding[1.1.0];bootstrap[3.3.7]</script>
<script src="shared/json2-min.js"></script>
<script src="shared/jquery.min.js"></script>
<link href="shared/shiny.css" rel="stylesheet" />
<script src="shared/shiny.min.js"></script>
<script src="htmlwidgets-0.9/htmlwidgets.js"></script>
<link href="leaflet-0.7.7/leaflet.css" rel="stylesheet" />
<script src="leaflet-0.7.7/leaflet.js"></script>
<link href="leafletfix-1.0.0/leafletfix.css" rel="stylesheet" />
<link href="leaflet-label-0.2.2/leaflet.label.css" rel="stylesheet" />
<script src="leaflet-label-0.2.2/leaflet.label.js"></script>
<script src="Proj4Leaflet-0.7.2/proj4-compressed.js"></script>
<script src="Proj4Leaflet-0.7.2/proj4leaflet.js"></script>
<script src="leaflet-binding-1.1.0/leaflet.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="shared/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<script src="shared/bootstrap/js/bootstrap.min.js"></script>
<script src="shared/bootstrap/shim/html5shiv.min.js"></script>
<script src="shared/bootstrap/shim/respond.min.js"></script>

</head>

<body>
  <div class="container-fluid">
    This is a map
    <div id="myMap" style="width:100%; height:400px; " class="leaflet html-widget html-widget-output"></div>
    <div class="form-group shiny-input-container">
      <input id="numeroDos" type="number" class="form-control" value="5"/>
    </div>
    <div id="mapPopupLink" class="shiny-text-output"></div>
  </div>
</body>

</html>