'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:

  1. If you want the controls to also be in the full screen, we need to full screen the container, not just the map.
  2. The leaflet map has a fixed height 400px so in fullscreen, first change its height to max screen height 100vh. This is not enough for the leaflet to adjust the map, we also need to fire the resize event.
  3. When users change fullscreen status, we need to resize the map back to the original size. To do so, we use addEventListener to watch screen change event. Depends on the browser, the event name is different, but we attach the same callback exitHandler.
  4. exitHandler first checks on different browsers, if we are on full screen or normal screen. If normal screen, resize the map to the original size.

enter image description here

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