SBista SBista - 5 months ago 17
R Question

Getting an input list containing inputs present in the current session

I want to retrieve the list of inputs in the current shiny session.
We can retrieve the list of inputs using

names(input)
.

I have a
uiOutput
and based on different conditions I am rendering different types inputs. The current problem I am facing is that when the condition changes the inputs from previous renderUI is also present in the list. Is there a way to get only the inputs in the current session?

To explain my query better I have the following sample code:

library(shiny)

ui <- fluidPage(

sliderInput(inputId = "slider",label = "", min = 1, max = 3, value = 1),

uiOutput("UI"),

actionButton(inputId = "btn", label = "Show Inputs"),

verbatimTextOutput(outputId = "textOp")
)


server <- function(input, output){

observeEvent(input$slider,{

if(input$slider == 1){

output$UI <- renderUI(
textInput("txt1",label = "Slider in position 1")
)

}else if(input$slider == 2){

output$UI <- renderUI(
textInput("txt2",label = "Slider in position 2")
)

}else{

output$UI <- renderUI(
textInput("txt3",label = "Slider in position 3")
)
}


})


observeEvent(input$btn,{

output$textOp <- renderText(

paste0(names(input), ",")
)


})
}



shinyApp(ui = ui, server = server)


In the above code when I first click on action button labelled "Show Input" I get the following text as the output:

btn, slider, txt1,

Now when I move the slider to 2 my output is as follows:

btn, slider, txt1, txt2,

Here txt1 was generated when the slider was at position 1, and this renderUI was overridden by
output$UI <- renderUI(textInput("txt2",label = "Slider in position 2"))
. I want an input list where
txt1
is not there. Is there a way to do that?

Answer Source

I came up with kind of a workaround, assuming you dont have any inputs that should take a value of NULL. You could set the values of the inputs, that you wish to remove, to NULL and filter for non - NULLs when you display the names.

library(shiny)

ui <- fluidPage(
  tags$script("
    Shiny.addCustomMessageHandler('resetValue', function(variableName) {
              Shiny.onInputChange(variableName, null);
              });
              "
  ),
  sliderInput(inputId = "slider",label = "", min = 1, max = 3, value = 1),

  uiOutput("UI"),

  actionButton(inputId = "btn", label = "Show Inputs"),

  verbatimTextOutput(outputId = "textOp")

)


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

  observeEvent(input$slider,{
    for(nr in 1:3){
      if(nr != input$slider) session$sendCustomMessage(type = "resetValue", message = paste0("txt", nr))      
    }
  })

  output$UI <- renderUI(
    textInput(paste0("txt", input$slider), label = paste0("Slider in position ", input$slider))
  )

  global <- reactiveValues()

  observe({
      inp = c()
      for(name in names(input)){
        if(!is.null(input[[name]])){
          inp <- c(inp, name)
        }
      }
      isolate(global$inputs <- inp)
  })

  output$textOp <- renderText({
    global$inputs
  })
}
shinyApp(ui = ui, server = server)