The title may be very confusing but I will try to explain my problem below in detail. I use the book "mastering shiny" section 10, "Dynamic UI" as guidance. The libraries used in R is
library(shiny)
library(tidyverse)
library(purrr)
I have a numericInput labelled as Number of modalities/ subspecialties required
.
I have a uiOutput called modality
in response that can have more modalities if the input from the numericInput changes. See below pictures if the number changes to 2, there will be 2 modalities boxes rather than 1.
The code for the above to work is listed below
# UI
numericInput("No_modalities", label = "Number of modalities/
subspecialties required",
value = 1, min = 1, max = 100, step = 1)
uiOutput("modality")
# Server
modality_names <- reactive(paste0("Modality ", seq_len(input$No_modalities)))
output$modality <- renderUI({
map(modality_names(), ~ textInput(.x, label = paste(.x," Name"),
value = isolate(input[[.x]])))
})
Now I want another uiOutput to have the labels as the input inside the Modality Name. Here's how I approached the problem. I created another uiOutput called ui_modality_minutes
, but for the labels, I want to use the labels from the input from modality_names()
. Please see below picture to better understand my aim. I want the input1 model 1
to be the first label, and input2 model 2
to be the second label, but my code will add model 1 and model 2 together rather than separately.
# UI
uiOutput("ui_modality_minutes")
# Server
modality_minutes <- reactive(paste0("Modality minutes ",
seq_len(input$No_modalities)))
output$ui_modality_minutes <- renderUI({
map(modality_minutes(), ~ numericInput(.x,
label = map(modality_names(),~input[[.x]]),
value = isolate(input[[.x]])))
})
Reproducible codes are shown below,
library(shiny)
library(tidyverse)
library(purrr)
ui <- fluidPage(
fluidRow(
numericInput("No_modalities", label = "Number of modalities/
subspecialties required",
value = 1, min = 1, max = 100, step = 1)),
fluidRow(
uiOutput("modality")
),
fluidRow(
uiOutput("ui_modality_minutes")
)
)
server <- function(input, output, session) {
modality_names <- reactive(paste0("Modality ", seq_len(input$No_modalities)))
modality_minutes <- reactive(paste0("Modality minutes ",
seq_len(input$No_modalities)))
output$modality <- renderUI({
map(modality_names(), ~ textInput(.x, label = paste(.x," Name"),
value = isolate(input[[.x]])))
})
output$ui_modality_minutes <- renderUI({
map(modality_minutes(), ~ numericInput(.x,
label = map(modality_names(),~input[[.x]]),
value = isolate(input[[.x]])))
})
}
shinyApp(ui, server)
Your last
map
function needs to be amap2
to simultaneously handle the generation of theinputId
and thelabel
. To get a character vector of the labels, I nest amap_chr
into themap2
function:You sometimes get an error when an
input
inmap_chr(modality_names(),~input[[.x]])
isNULL
, but for your functionality it doesn't make a difference (then no name is shown).Edit
Now including Subaru Spirit's solution to get rid of
NULL