Search code examples
cssrshinyshinywidgets

How to bring pop-ups for long text string selection items forward in front of modal they are rendered from when using virtualSelectInput()?


In running the below R Shiny code using the virtualSelectInput() function from shinyWidgets, hover-over pop-ups should appear for selection items that are long text strings. Works fine when rendered outside a modal. But when rendered in a modal in the below code, those pop-ups are obscured by the modal itself. I've tried bringing the pop-ups forward by fooling around with z-index and other CSS tricks, but no luck yet. Any suggestions? I chose virtualSelectInput() for its ability to quickly handle 1000+ item lists.

In the code I left in items making the modal draggable and allowing the user to interact with both underlying UI and the modal while the modal is rendered, important features that must be retained. Other than that, the code is MWE.

library(shiny)
library(shinyWidgets)
library(shinyjqui)

ui <- fluidPage(
  tags$head(
    tags$style(HTML("
      .modal-backdrop {
        display: none !important;
      }
      .modal {
        pointer-events: none; 
      }
      .modal-content {
        pointer-events: auto; 
      }
    "))
  ),
  actionButton("showModalBtn", "Show modal")
)

server <- function(input, output, session) {
  observeEvent(input$showModalBtn, {
    modal <- modalDialog(
      title = "",  
      tags$table(
        tags$tr(
          tags$th("CS"),
          tags$th("WF")
        ),
        tags$tr(
          tags$td(
            virtualSelectInput(
              inputId = "CS_select",
              label = NULL,  
              choices = c("Option 1 is a crazy looooong string", "Option 2 is the longeeeest string"),
              width = "150px" # Leave this width
            )
          ),
          tags$td(
            virtualSelectInput(
              inputId = "WF_select",
              label = NULL,  
              choices = c("Option A is longest string ever", "Option B"),
              width = "150px" # Leave this width
            )
          )
        )
      )
    )
    showModal(modal)
    jqui_draggable(ui = "#shiny-modal .modal-content")  # Make the modal draggable
    jqui_resizable(ui = "#shiny-modal .modal-content")  # Make the modal resizable
  })
}

shinyApp(ui, server)

Solution

  • Virtual-Select can be modified by passing a zIndex property (see the documentation), and virtualSelectInput has a ... argument which allows for passing additional arguments. From ?virtualSelectInput:

    ...

    Other arguments passed to JavaScript method, see virtual-select documentation for a full list of options.

    Hence you can pass a suitable zIndex to virtualSelectInput (needed is 10000), this yields readable tooltips:

    library(shiny)
    library(shinyWidgets)
    library(shinyjqui)
    
    ui <- fluidPage(
      tags$head(
        tags$style(HTML("
          .modal-backdrop {
            display: none !important;
          }
          .modal {
            pointer-events: none; 
          }
          .modal-content {
            pointer-events: auto; 
          }
        "))
      ),
      actionButton("showModalBtn", "Show modal")
    )
    
    server <- function(input, output, session) {
      observeEvent(input$showModalBtn, {
        modal <- modalDialog(
          title = "",  
          tags$table(
            tags$tr(
              tags$th("CS"),
              tags$th("WF")
            ),
            tags$tr(
              tags$td(
                virtualSelectInput(
                  inputId = "CS_select",
                  label = NULL,  
                  choices = c("Option 1 is a crazy looooong string", "Option 2 is the longeeeest string"),
                  width = "150px", # Leave this width,
                  zIndex = 10000
                )
              ),
              tags$td(
                virtualSelectInput(
                  inputId = "WF_select",
                  label = NULL,  
                  choices = c("Option A is longest string ever", "Option B"),
                  width = "150px", # Leave this width
                  zIndex = 10000
                )
              )
            )
          )
        )
        showModal(modal)
        jqui_draggable(ui = "#shiny-modal .modal-content")  # Make the modal draggable
        jqui_resizable(ui = "#shiny-modal .modal-content")  # Make the modal resizable
      })
    }
    
    shinyApp(ui, server)
    

    enter image description here