www
www

Reputation: 39154

Refer to the Updated UI Input ID and Calculate the Sum in Shiny

I would like to design a Shiny app with two buttons. Users can click the "Add UI" button as many times as they want, which will return text boxes. Users can then type numbers to the input boxes, click the "Sum" button, and calculate the total.

Below is my current code, modified from the sample code from ?insertUI. My question is I am not sure how to refer to the input id from the updated UI (in this case, the new text boxes). My current attempt cannot calculate the sum. The end result is always 0.

# Define UI
ui <- fluidPage(
  actionButton("add", "Add UI"),
  actionButton("sum", "Sum"),

  # Report the output
  h4("The total from input"),
  textOutput("text")
)

# Server logic
server <- function(input, output, session) {
  observeEvent(input$add, {
    insertUI(
      selector = "#add",
      where = "afterEnd",
      ui = textInput(paste0("txt", input$add),
                     "Insert some text")
    )
  })

  # Calculate the total from the text inputs
  output$text <- eventReactive(input$sum, {
    as.character(sum(as.numeric(unlist(mget(ls(pattern = "^txt"))))))
  })
}

# Complete app with UI and server components
shinyApp(ui, server)

Upvotes: 1

Views: 357

Answers (1)

Nate
Nate

Reputation: 10671

You can use the special Shiny variable input to check and access the current inputs (and values) in your app. Thus you can get at newly inserted UI elements (assuming they all follow a pattern) and compute against them.

  output$text <- eventReactive(input$sum, {
    txt_inpt_names <- names(input)[grepl("^txt", names(input))]
  
    sum(sapply(txt_inpt_names, function(x) as.numeric(input[[x]])), na.rm = T)
  })

Worth noting that Shiny requires single (one-at-a-time) access to input values so thats why sapply() is required and not just input[[txt_inpt_names]].

Upvotes: 2

Related Questions