Here is a simple shiny app:
library(shiny)
library(leaflet)
nc = sf::st_read(system.file("shape/nc.shp", package="sf"))
ui <- function(request){
tagList(
selectInput("color", "color", c("blue", "red", "green")),
leafletOutput("map")
)
}
server <- function(
input,
output,
session
){
output$map <- renderLeaflet({
leaflet(nc) %>%
addPolygons(color = input$color)
})
}
shinyApp(ui, server)
I want to bind an event on click on each polygon, but I want it to happen from the client-side only, I don't want it to go through R. For example, I would like to send an alert when the user click on the polygon.
I've got some hacky code that does that, but I would love to have a clean way to do it.
What I'm looking for is a way to define from R something that would look like addPolygon(onClick = "alert('hello there')")
.
To be clear I don't want this to go through the server, I want everything to happen in the browser.
It works with the following JS code (in ext/script.js)
$(document).ready(function() {
Shiny.addCustomMessageHandler('bindleaflet', function(arg) {
$("#" + arg).find("path").remove();
wait_for_path(arg);
})
});
var wait_for_path = function(id) {
if ($("#" + id).find("path").length !== 0) {
$("#" + id).find(".leaflet-interactive").on("click", function(x) {
alert("hey")
})
} else {
setTimeout(function() {
wait_for_path(id);
}, 500);
}
}
Then in R
library(shiny)
library(leaflet)
nc = sf::st_read(system.file("shape/nc.shp", package="sf"))
ui <- function(request){
tagList(
tags$script(src = "ext/script.js"),
selectInput("color", "color", c("blue", "red", "green")),
leafletOutput("map")
)
}
server <- function(
input,
output,
session
){
addResourcePath("ext", "ext")
output$map <- renderLeaflet({
session$sendCustomMessage("bindleaflet", "map")
leaflet(nc) %>%
addPolygons(color = input$color)
})
}
shinyApp(ui, server)
But that seems overly complicated for something you would define as such when building the leaflet in pure JS:
onEachFeature: function(feature, layer) {
layer.on({
click: (function(ev) { alert('hey') } )
Is there a way to natively do it when building the app in R?
I've built a reprex of my current code here: https://github.com/ColinFay/leaflet-shiny-click-event
Thanks,
Colin
htmlwidgets::onRender
to pass the JS - here and here are some examples.