Reputation: 706
In my reprex below, Number duplicates the inputs. I am stuck on how to achieve two things.
If the Contractor radio button option is selected, show a text input with label "Name of Contractor".
How can I have the radio button input set as empty? I know selected = character(0)
achieves this, but it causes another challenge: if an option is selected, and then Number is changed, the radio button selection will disappear. In my reprex, the radio button selection will not be affected after Number is changed, but the default selection is the first choice, whereas I would like the default to be empty.
library(shiny)
ui <- fluidPage(
numericInput("n", "Number", value = 1),
uiOutput("col")
)
server <- function(input, output, session) {
# Dynamic UI: Multiple Controls -------------------------------------------
col_names <- reactive(paste0("staff_attended_", seq_len(input$n)))
output$col <- renderUI({
map(
col_names(),
~ tagList(
selectInput(
.x,
label = "Staff Attended",
choices = letters,
selected = isolate(input[[.x]]),
multiple = TRUE
),
radioButtons(
paste0(.x, "_type"),
"Staff Attended: Shift/Call-In/Contractor?",
choices = c("Shift", "Call-In", "Contractor"),
selected = isolate(input[[paste0(.x, "_type")]])
)
)
)
})
}
shinyApp(ui, server)
Upvotes: 0
Views: 187
Reputation: 9133
If the Contractor radio button option is selected, show a text input with label "Name of Contractor".
Therefore we can use a conditionalPanel
which contains a textInput
. The condition can be written as
paste0(
"(document.querySelector('input[name=\"",
.x,
"_type\"]:checked') || {value: 'dummy'}).value === 'Contractor'"
)
Explanation:
document.querySelector
call aims for the checked value of the
radioButtons
. The relevant checkbox id is assigned by .x
inside
your map
call. It shall return TRUE
if this value is "Contractor".radioButtons
when starting the app, the querySelector
would be null
while being in this state. Hence, the || {value: 'dummy'})
will yield a dummy value such that there won't be an error and the textInput
is hidden by the start of the app. Otherwise, the ||
operator will short-circuit.How can I have the radio button input set as empty? I know selected = character(0) achieves this, but it causes another challenge: if an option is selected, and then Number is changed, the radio button selection will disappear...
In order to retain the selection when the number is changed, we put an observeEvent
on input$n
and use an updateRadioButtons
, which will affect the selected
parameter using isolate
.
observeEvent(input$n, {
map(col_names(),
~ tagList(
updateRadioButtons(session, paste0(.x, "_type"),
selected = isolate(input[[paste0(.x, "_type")]]))
))
})
Complete minimal example:
library(shiny)
ui <- fluidPage(numericInput("n", "Number", value = 1),
uiOutput("col"))
server <- function(input, output, session) {
# Dynamic UI: Multiple Controls -------------------------------------------
col_names <-
reactive(paste0("staff_attended_", seq_len(input$n)))
observeEvent(input$n, {
map(col_names(),
~ tagList(
updateRadioButtons(session, paste0(.x, "_type"),
selected = isolate(input[[paste0(.x, "_type")]]))
))
})
output$col <- renderUI({
map(col_names(),
~ tagList(
selectInput(
.x,
label = "Staff Attended",
choices = letters,
selected = isolate(input[[.x]]),
multiple = TRUE
),
radioButtons(
paste0(.x, "_type"),
"Staff Attended: Shift/Call-In/Contractor?",
choices = c("Shift", "Call-In", "Contractor"),
selected = character(0)#isolate(input[[paste0(.x, "_type")]])
),
conditionalPanel(
paste0(
"(document.querySelector('input[name=\"",
.x,
"_type\"]:checked') || {value: 'dummy'}).value === 'Contractor'"
),
textInput("NameContractor", "Name of Contractor")
)
))
})
}
shinyApp(ui, server)
Upvotes: 1