简体   繁体   中英

R Shiny: Dynamically calling modules depending on user input

I am trying to create an app that will dynamically call modules depending on user input. In this example, I have a simple selectInput() which defaults to 1, with choices 1 and 2. What I want is for any time the user selects 1, the server calls a "first" module, which just has a textInput() box that displays "Your selection is (user input)", or in the case of 1, "Your selection is 1". Otherwise, if user selects 2, I want to call a different module, which is an add/remove button module, which in turn calls "first" module. Essentially, it selectInput() value of 2 will do the same as selectInput() value of 1, except that in addition to the UI output of "first" module, it will have an add and remove action button that if pressed will call more of the "first" module ui and server components. I have it working if 1 is selected, but for selectInput() of 2, it does not seem to call the addRmBtn module. Code below, thanks!

library(shiny)

firstUI <- function(id) { uiOutput(NS(id, "first")) }

firstServer <- function(input, output, session, inData) {
    ns = session$ns

    output$first <- renderUI({
        textInput(ns("selection"), ns("selection"), value = paste0("Your selection is ", inData))
    })

}

removeFirstUI <- function(id) {
    removeUI(selector = paste0('#', NS(id, "first")))
}

addRmBtnUI <- function(id) {
    ns <- NS(id)

    tags$div(
    actionButton(inputId = ns('insertParamBtn'), label = "Add"),
    actionButton(ns('removeParamBtn'), label = "Remove"),
    hr(),
    tags$div(id = ns('placeholder'))
  )
}

addRmBtnServer <- function(input, output, session, moduleToReplicate, ...) {
    ns = session$ns

    params <- reactiveValues(btn = 0)

    observeEvent(input$insertParamBtn, {
        params$btn <- params$btn + 1

        callModule(moduleToReplicate$server, id = params$btn, ...)
        insertUI(
            selector = paste0('#', ns('placeholder')),
            ui = moduleToReplicate$ui(ns(params$btn))
            )
            })

    observeEvent(input$removeParamBtn, {
        moduleToReplicate$remover(ns(params$btn))
        params$btn <- params$btn - 1
    })
}

ui <- fluidPage(
  #addRmBtnUI("addRm"),
  column(12, selectInput("inp", label = "Select", choices = list(1, 2), selected = 1)),
  column(12, uiOutput("inpChoice"))
)                       

server <- function(input, output, session) {

    observeEvent(input$inp, {
       if (input$inp == 1) {
           callModule(firstServer, id = 0, inData = input$inp)
           output$inpChoice <- renderUI({ firstUI(0) })
       } else {
            callModule(addRmBtnServer,
                id = "inpChoice",
                moduleToReplicate = list(
                    ui = firstUI,
                    server = firstServer,
                    remover = removefirstIU
                    ),
                inData = input$inp
                )

            }

        })
}

shinyApp(ui = ui, server = server)

Try using a conditionalPanel() in the UI to adapt the conditions to the user input.

Maybe something like

conditionalPanel(condition = "input.inp=='2'",[do second module stuff here])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM