For some reason the displaying of bsModal content seems to go wrong when it is triggered by an observeEvent
from the server side, images and or text don't appear, and it also seems to cause a disabling of Sweetalerts
in some cases (which are basically prebuild modals).
I tagged shinyjs
for this reason, since the app includes interaction with it.
Besides a very long post, and complicated issue, I hope that the bsmodal
part as well as the sweetalert
coding with shinyJS
, which is a copy of work by Dean Attali may help some other people who happen to read this. If you find it useful, give the post an upvote.
A full app with scenario 1, 2 and 3 is found below. Scenarios 4 and further are not in the full app, because some cause other parts of the app to stop working as well as soon as you add their code. I suggest to try the app at the end, and then read through my scenarios. (tried to make it as clear as possible.)
I'm using bsModals
to add new functionality to my Shiny
program (very large complex app), and discovered something strange while trying to incorporate images into bsmodals
. I did some research into when the problem occurs, and present a test app here with several scenarios.
My primary issue:
For my purposes I need to figure out why scenario 7b doesn't work, i.e. bsmodal from server with image and observeEvent to activate it,
2nd main question is, can you somehow code the trigger = input$button1
argument in the bsmodal as trigger = values$variable
somehow? I tried this but could not figure it out.
The main problem seems to revolve around the difference in behaviour of trigger =
argument inside bsmodal()
versus using observeEvent()
with toggleModal()
Scenario 1: works
This on the UI side for instance works fine:
i.e. the modal
appears, and the sweetalert
in the app shows up on start
actionButton("show1", "Show modal 1"),
bsModal(id= 'InfoModal1',title = "This modal works", trigger = "show1", "triggered by clicking button 1, trigger argument in UI code for bsModal without image"),
Scenario 2: works
Adding an image to the modal, still all through UI side, works fine, image appears:
actionButton("show2", "Show modal 2"),
bsModal(id= 'InfoModal2',title = "This modal works", trigger = "show2",
img(src="https://www.rstudio.com/wp-content/uploads/2014/07/RStudio-Logo-Blue-Gradient.png", width="550", height="200"),
br(), "triggered by clicking button 2, trigger argument in UI code for bsModal"),
Scenario 3: works partially
Now we try to have it triggered by the server side of things. Which is usefull if it is for instance needed to have a modal that doesn't come from a button click, but a variable value changing. The modal appears, and this variation doesn't cause problems with the sweetalert, but no text content in the modal body!
ui side:
actionButton("show3", "Show modal 3"),
bsModal(id= 'InfoModal3',title = "This modal works but content text does NOT show up!", "triggered by clicking button 3, and use observeEvent in the server, without image"),
server side:
observeEvent(input$show3, { toggleModal(session, "InfoModal3", toggle = "toggle") })
Scenario 4: does not work at all, and sweetalert now broken too
If I add an image to scenario 3, it's the same result. To do this I add the following code behind the senario 3 code in the UI and a second observer to the server, and I also notice, that if I don't run rm(UI) first, most of the time the ui will be wrong, i.e. without button nr 4
ui side
actionButton("show4", "Show modal 4"),
bsModal(id= 'InfoModal4',title = "This modal works but content image does NOT show up!", img(src="https://www.rstudio.com/wp-content/uploads/2014/07/RStudio-Logo-Blue-Gradient.png", width="550", height="200"),"triggered by clicking button 4, trigger modal by observeEvent in the server, without image")
server side:
observeEvent(input$show4, { toggleModal(session, "InfoModal4", toggle = "toggle") })
Scenario 5: WORKS -> build basic bsModal
with renderUI()
with trigger in it from the server side
replace whole tabitems()
section in working app with this in the UI:
tabItems(
tabItem(tabName = 'tab1',
actionButton("show5", "Show modal 5"),
uiOutput("MyModal5")
))))
and replace server with:
server <- function(input, output, session) {
shinyjs::js$swal( title = '<span style="color:#339FFF; font-size: 30px">Finished loading app<span>',
text = '<span style="color:black; font-size: 16px">version: 1.0.0 <br> written by: M.A. van Dijk<span>',
imageUrl= "https://www.rstudio.com/wp-content/uploads/2014/07/RStudio-Logo-Blue-Gradient.png" )
output$MyModal5 <- renderUI({ bsModal(id= 'InfoModal5',title = "This modal works but content text does NOT show up!", trigger = "show5", " build by server, and triggered by clicking button 5 with trigger argument in modal, without image") })
}
Scenario 6: works with or without image, but.....
ui part is :
tabItems(
tabItem(tabName = 'tab1',
actionButton("show6", "Show modal 6"),
uiOutput("MyModal6")
))))
server part after the swal function:
output$MyModal6 <- renderUI({ bsModal(id= 'InfoModal6',title = "This modal works and content text does show up!", trigger = "show6", " build by server, and triggered by clicking button 6 and an observeEvent in the server, without image") })
}
or the version of server WITH image:
output$MyModal6 <- renderUI({ bsModal(id= 'InfoModal6',title = "This modal works and content text does show up!", trigger = "show6", img(src = "https://www.rstudio.com/wp-content/uploads/2014/07/RStudio-Logo-Blue-Gradient.png", width="550", height="200"),
"build by server, and triggered by clicking button 6 and a trigger argument in the bsmodal, with image") })
*I can't use this in my program however when I want to have the modal triggered by a variable rather than a button click. To do that, I should use an observeEvent like the next scenario, I think. Unless there is a way to use "trigger = "some reactive value" *
Scenario 7: Works, without an image, not with....
I found out that it does work with an observeEvent(input$show7)
instead of trigger = "show7"
in the dummy app to do everything from the server, until I add an img(scr.... part.
ui side:
tabItems(
tabItem(tabName = 'tab1',
actionButton("show7", "Show modal 7"),
uiOutput("MyModal7")
))))
server side
output$MyModal7 <- renderUI({ bsModal(id= 'InfoModal7',title = "This modal works and content text does show up!", "build by server, and triggered by clicking button 7 and a trigger argument in the bsmodal, with image") })
observeEvent(input$show7, { toggleModal(session, "InfoModal7", toggle = "toggle") })
. .To add the image, replace the output$modal7 with
output$MyModal7 <- renderUI({ bsModal(id= 'InfoModal7',title = "This modal doesn't work", img(src="https://www.rstudio.com/wp-content/uploads/2014/07/RStudio-Logo-Blue-Gradient.png", width="550", height="200"),
"build by server, and triggered by clicking button 7 and a trigger argument in the bsmodal, with image") })
. . .
WORKING APP FOR Scenario 1, 2 and 3:
library(shiny)
library(shinyBS)
library(shinyjs)
jscode <- "
shinyjs.swal = function(params) {
var defaultParams = {
title: null,
text : null,
imageUrl: null
};
params = shinyjs.getParams(params, defaultParams);
swal({title : params.title, text : params.text, imageUrl : params.imageUrl,
imageSize: '400x400',
html: true,
showCancelButton : false,
showConfirmButton : true,
closeOnConfirm: true,
confirmButtonColor: '#339FFF',
allowOutsideClick: true }); };"
ui <- shinydashboard::dashboardPage(
dashboardHeader(title = "Dummy App"),
dashboardSidebar(
tags$head(
tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.0.1/sweetalert.min.js"), ### code for the sweetalerts
tags$link(rel = "stylesheet", type = "text/css", ### code for the sweetalerts
href = "https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.0.1/sweetalert.min.css") ### code for the sweetalerts
),
sidebarMenu(id = 'sidebarmenu',
menuItem("My Tab", tabName = 'tab1'))),
dashboardBody(
shinyjs::useShinyjs(), ### code for the sweetalerts
shinyjs::extendShinyjs(text = jscode), ### code for the sweetalerts
tabItems(
tabItem(tabName = 'tab1',
actionButton("show1", "Show modal 1"),
bsModal(id= 'InfoModal1',title = "This modal works", trigger = "show1", "triggered by clicking button 1, trigger argument in UI code for bsModal without image"),
actionButton("show2", "Show modal 2"),
bsModal(id= 'InfoModal2',title = "This modal works", trigger = "show2",
img(src="https://www.rstudio.com/wp-content/uploads/2014/07/RStudio-Logo-Blue-Gradient.png", width="550", height="200"),
br(), "triggered by clicking button 2, trigger argument in UI code for bsModal"),
actionButton("show3", "Show modal 3"),
bsModal(id= 'InfoModal3',title = "This modal works but content text does NOT show up!", "triggered by clicking button 3, trigger modal by observeEvent in the server, without image")
))))
server <- function(input, output, session) {
shinyjs::js$swal( title = '<span style="color:#339FFF; font-size: 30px">Finished loading app<span>',
text = '<span style="color:black; font-size: 16px">version: 1.0.0 <br> written by: M.A. van Dijk<span>',
imageUrl= "https://www.rstudio.com/wp-content/uploads/2014/07/RStudio-Logo-Blue-Gradient.png" )
observeEvent(input$show3, { toggleModal(session, "InfoModal3", toggle = "toggle") })
}
shinyApp(ui = ui, server = server)