英文:
How to show or hide a textInput in R shiny depending on a radioButton choice?
问题
在我的reprex中,Number复制了输入。我卡在了如何实现两件事情上。
1)如果选择了承包商单选按钮选项,请显示一个带有标签“承包商名称”的文本输入。
2)如何将单选按钮输入设置为空?我知道selected = character(0)
可以实现这一点,但它会带来另一个挑战:如果选择了一个选项,然后更改Number,单选按钮的选择将消失。在我的reprex中,单选按钮的选择不会在更改Number后受到影响,但默认选择是第一个选项,而我希望默认选择为空。
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)
英文:
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)
答案1
得分: 1
这是一个示例。
问题1: 如果选择承包商单选按钮选项,显示带有标签“承包商名称”的文本输入。
因此,我们可以使用conditionalPanel
,其中包含一个textInput
。条件可以编写为
paste0(
"(document.querySelector('input[name=\"",
.x,
"_type\"]:checked') || {value: 'dummy'}).value === 'Contractor'"
)
解释:
document.querySelector
调用旨在获取radioButtons
的选中值。相关的复选框id由.x
在您的map
调用内分配。如果该值为“Contractor”,它将返回TRUE
。- 由于您希望在启动应用程序时有空的
radioButtons
,所以在这种状态下,querySelector
将为null
。因此,|| {value: 'dummy'})
将生成一个虚拟值,以便不会出现错误,并且在应用程序启动时隐藏textInput
。否则,||
运算符将短路。
问题2: 如何将单选按钮输入设置为空?我知道 selected = character(0)
可以实现这一点,但它会引发另一个问题:如果选择了一个选项,然后更改数字,单选按钮的选择将消失...
为了在更改数字时保留选择,我们对 input$n
使用 observeEvent
,并使用 isolate
使用 updateRadioButtons
来影响 selected
参数。
observeEvent(input$n, {
map(col_names(),
~ tagList(
updateRadioButtons(session, paste0(.x, "_type"),
selected = isolate(input[[paste0(.x, "_type")]]))
))
})
完整的最小示例:
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)
英文:
Here is one example.
Question 1: 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:
- The
document.querySelector
call aims for the checked value of the
radioButtons
. The relevant checkbox id is assigned by.x
inside
yourmap
call. It shall returnTRUE
if this value is "Contractor". - Since you would like to have empty
radioButtons
when starting the app, thequerySelector
would benull
while being in this state. Hence, the|| {value: 'dummy'})
will yield a dummy value such that there won't be an error and thetextInput
is hidden by the start of the app. Otherwise, the||
operator will short-circuit.
Question 2: 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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论