moman822
moman822

Reputation: 1954

R Shiny sequential use of modals

I want to check some user inputted data, testing some conditions and alerting via modalDialog() to get more user input (e.g. prompt X is NA; is this correct? Y/N).

However, I have found that if I put multiple showModal(modalDialogFunction()) calls in an observeEvent, only the last one will be evaluated for the user in that the modal pops up, etc. The print statements verify the conditions are met.

How can I execute sequential modals in this or a similar format?

Single file app: play around with numericInput()s to see how modals are executed.

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      numericInput("first", label="First", value=0),
      numericInput("second", label="Second", value=0)
    ),
    mainPanel(
      actionButton("click", label="Click")
    )
  )
)

server <- function(input, output) {
  firstModal <- function(){
    modalDialog(
      p("First is greater than zero"),
      actionButton("clickHere", label="Click to continue")
    )
  }

  secondModal <- function(){
    modalDialog(
      p("Second is greater than zero"),
      actionButton("clickAgain", label="Click to continue again")
    )
  }

  observeEvent(input$click, {
    if(input$first>0){
      print("First is greater than 0")
      showModal(firstModal())
    }

    if(input$second>0){
      print("Second is greater than 0")
      showModal(secondModal())
    }
  })
}

shinyApp(ui = ui, server = server)

Upvotes: 4

Views: 2094

Answers (1)

shosaco
shosaco

Reputation: 6165

I found that it is not possible to have two input buttons having the same ID and being visible at the same time. To solve that problem, the button that opens your very first modal needs a different ID - all the "Next"-Buttons in the Modals can share one ID, since they are never visible at the same time. Check this working example:

ui <- fluidPage(
      actionButton("openFirst", label="Click")
)

server <- function(input, output) {

  # function to create a modal, can be different functions as well
  makeModal <- function(text){
    modalDialog(
      footer=list(actionButton("click", label="Click to continue"), modalButton("Close")),
      numericInput("number", "Enter a number", value=0),
      p(text)
    )
  }

  # open the first modal
  observeEvent(input$openFirst, {
    showModal(makeModal("first one opened"))
  })

  # open a new modal at button click.
  observeEvent(input$click, {
    if(input$number > 15){ showModal(makeModal("input was greater than 15!"))
    }else if(input$number > 5){ showModal(makeModal("input was greater than five!"))
    }else{
      showModal(makeModal("Input was not greater than five!"))
    }
  })
}

shinyApp(ui = ui, server = server)

Upvotes: 2

Related Questions