'How to make leaflet map and absolutePanel of inputs / outputs full screen in shiny
I want to click a button to make a leaflet map and all overlayed inputs full screen.
Using the following example, I can make the map full screen but I lose the inputs (in this case, h1("test")). Or I can preserve the inputs on top of the map but then the map is not drawn full screen as expected.
library(leaflet)
library(shiny)
js <- "
function openFullscreen(elem) {
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) { /* Firefox */
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) { /* IE/Edge */
elem.msRequestFullscreen();
}
}"
ui <- fluidPage(
tags$scrip(HTML(js)),
actionButton("fullscreen", "Full Screen Container",
onclick = "openFullscreen(document.getElementById('map_container'))"),
actionButton("fullscreen", "Full Screen Map Only",
onclick = "openFullscreen(document.getElementById('map'))"),
div(
id = "map_container",
leafletOutput(height = "100px", "map"),
absolutePanel(
top = 20,
right = 20,
h1("test", style = "color:white")
)
)
)
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() %>%
addProviderTiles('Esri.WorldImagery') %>%
setView(lng = 118.2437, lat = 34.0522, zoom = 5)
})
}
shinyApp(ui, server)
Update
I tried adding z-index: 10000 !important; to the h1() style based on this, but it is still hidden when maximizing the leaflet map.
Solution 1:[1]
library(leaflet)
library(shiny)
js <- "
function openFullscreen(elem) {
var map = $(elem).find('.leaflet.html-widget');
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) { /* Firefox */
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) { /* IE/Edge */
elem.msRequestFullscreen();
}
$(map).css('height', '100vh').trigger('resize');
}
document.addEventListener('fullscreenchange', exitHandler, false);
document.addEventListener('mozfullscreenchange', exitHandler, false);
document.addEventListener('MSFullscreenChange', exitHandler, false);
document.addEventListener('webkitfullscreenchange', exitHandler, false);
function exitHandler(){
if (document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement) return;
$('#map').css('height', '400px').trigger('resize');
}
"
ui <- fluidPage(
actionButton(
"fullscreen", "Full Screen Container",
onclick = "openFullscreen(document.getElementById('map_container'))"
),
div(
id = "map_container",
leafletOutput(height = "400px", "map"),
absolutePanel(
top = 20,
right = 20,
style = "color: #FFF",
h1("test", style = "color:white"),
selectInput("in2", "choose", 1:5),
numericInput("in3", "number", 0, 0, 10)
)
),
tags$scrip(HTML(js))
)
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() %>%
addProviderTiles('Esri.WorldImagery') %>%
setView(lng = 118.2437, lat = 34.0522, zoom = 5)
})
}
shinyApp(ui, server)
Explain:
- If you want the controls to also be in the full screen, we need to full screen the container, not just the map.
- The leaflet map has a fixed height
400pxso in fullscreen, first change its height to max screen height100vh. This is not enough for the leaflet to adjust the map, we also need to fire theresizeevent. - When users change fullscreen status, we need to resize the map back to the original size. To do so, we use
addEventListenerto watch screen change event. Depends on the browser, the event name is different, but we attach the same callbackexitHandler. exitHandlerfirst checks on different browsers, if we are on full screen or normal screen. If normal screen, resize the map to the original size.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

