shiny
shiny copied to clipboard
Serverless Modal
It would be useful if there was a function to create a modal and show/hide it without needing to generate the modal on the fly through the server every time. This would be useful when the content of the modal needs to persist between views.
The shinyBS package has the bsModal function which basically does what I'm talking about but doesn't have the same level of customization as the standard modalDialog function.
I mocked up a rough idea of how this could work using html and javascript.
library(shiny)
ui <- fluidPage(
actionButton("showModal", "Show Modal"),
tags$div(id = "modal",
class = "modal in",
style = "display: none;",
tags$div(class = "modal-dialog",
style = "width: 95%;",
tags$div(class = "modal-content",
tags$div(class = "modal-header",
tags$h4(class = "modal-title",
"Modal Title",
tags$button(id = "close-modal",
type = "button",
class = "btn btn-default action-button shiny-bound-input",
style = "float: right; background-color: transparent; border: none;",
tags$i(class = "fa fa-times",
role = "presentation",
`aria-label` = "times icon")))),
tags$div(class = "modal-body",
"[Modal Content]")))),
tags$script("var modal = document.getElementById('modal');
document.getElementById('showModal').onclick = function() {
modal.style.display = 'block';
document.getElementsByTagName('body')[0].classList.add('modal-open');
}
document.getElementById('close-modal').onclick = function() {
modal.style.display = 'none';
document.getElementsByTagName('body')[0].classList.remove('modal-open');
}
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = 'none';
document.getElementsByTagName('body')[0].classList.remove('modal-open');
}
}")
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
You can try my package shinyChakraUI, but it is a bit complicated to use.
library(shiny)
library(shinyChakraUI)
ui <- chakraPage(
br(),
chakraComponent(
"mycomponent",
chakraModal(
inputId = "modal",
openButton = Tag$Button(
colorScheme = "orange",
"Open Modal"
),
header = Tag$ModalHeader(
fontSize = "lg",
fontWeight = "bold",
"Modal title"
),
body = Tag$ModalBody(
Tag$RadioGroup(
id = "radiogrp",
value = "3",
Tag$Stack(
direction = "row",
Tag$Radio(value = "1", "First"),
Tag$Radio(value = "2", "Second"),
Tag$Radio(value = "3", "Third")
)
),
),
footer = Tag$ModalFooter(
Tag$ButtonGroup(
spacing = "3",
Tag$Button(
action = "close",
value = "CLOSE",
"Close"
),
Tag$Button(
action = "cancel",
colorScheme = "red",
"Cancel"
)
)
)
)
)
)
server <- function(input, output, session){
observe({
print(input[["modal"]])
print(input[["radiogrp"]])
})
}
shinyApp(ui, server)

There is ModalDialogUI in the shinyGizmo package.