在R Shiny中,根据单选按钮的选择如何显示或隐藏textInput?

huangapple go评论68阅读模式
英文:

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.

  1. If the Contractor radio button option is selected, show a text input with label "Name of Contractor".

  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 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 &lt;- fluidPage(
  numericInput(&quot;n&quot;, &quot;Number&quot;, value = 1),
  uiOutput(&quot;col&quot;)
)


server &lt;- function(input, output, session) {
  
  # Dynamic UI: Multiple Controls -------------------------------------------
  
  col_names &lt;- reactive(paste0(&quot;staff_attended_&quot;, seq_len(input$n)))
  
  output$col &lt;- renderUI({
    map(
      col_names(), 
      ~ tagList(
          selectInput(
            .x,
            label = &quot;Staff Attended&quot;,
            choices = letters,
            selected = isolate(input[[.x]]),
            multiple = TRUE
          ),
          
          radioButtons(
            paste0(.x, &quot;_type&quot;), 
            &quot;Staff Attended: Shift/Call-In/Contractor?&quot;,
            choices = c(&quot;Shift&quot;, &quot;Call-In&quot;, &quot;Contractor&quot;),
            selected = isolate(input[[paste0(.x, &quot;_type&quot;)]])
          )
          
      )
    )
  })
}

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)

在R Shiny中,根据单选按钮的选择如何显示或隐藏textInput?
在R Shiny中,根据单选按钮的选择如何显示或隐藏textInput?

英文:

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(
   &quot;(document.querySelector(&#39;input[name=\&quot;&quot;,
   .x,
   &quot;_type\&quot;]:checked&#39;) || {value: &#39;dummy&#39;}).value === &#39;Contractor&#39;&quot;
)

Explanation:

  • The 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".
  • Since you would like to have empty radioButtons when starting the app, the querySelector would be null while being in this state. Hence, the || {value: &#39;dummy&#39;}) 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.

在R Shiny中,根据单选按钮的选择如何显示或隐藏textInput?

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, &quot;_type&quot;),
                               selected = isolate(input[[paste0(.x, &quot;_type&quot;)]]))
        ))
})

在R Shiny中,根据单选按钮的选择如何显示或隐藏textInput?

Complete minimal example:

library(shiny)

ui &lt;- fluidPage(numericInput(&quot;n&quot;, &quot;Number&quot;, value = 1),
                uiOutput(&quot;col&quot;))


server &lt;- function(input, output, session) {
    # Dynamic UI: Multiple Controls -------------------------------------------
    
    col_names &lt;-
        reactive(paste0(&quot;staff_attended_&quot;, seq_len(input$n)))
    
    observeEvent(input$n, {
        map(col_names(),
            ~ tagList(
                updateRadioButtons(session, paste0(.x, &quot;_type&quot;),
                                   selected = isolate(input[[paste0(.x, &quot;_type&quot;)]]))
            ))
    })
    
    output$col &lt;- renderUI({
        map(col_names(),
            ~ tagList(
                selectInput(
                    .x,
                    label = &quot;Staff Attended&quot;,
                    choices = letters,
                    selected = isolate(input[[.x]]),
                    multiple = TRUE
                ),
                
                radioButtons(
                    paste0(.x, &quot;_type&quot;),
                    &quot;Staff Attended: Shift/Call-In/Contractor?&quot;,
                    choices = c(&quot;Shift&quot;, &quot;Call-In&quot;, &quot;Contractor&quot;),
                    selected = character(0)#isolate(input[[paste0(.x, &quot;_type&quot;)]])
                ),
                
                conditionalPanel(
                    paste0(
                        &quot;(document.querySelector(&#39;input[name=\&quot;&quot;,
                        .x,
                        &quot;_type\&quot;]:checked&#39;) || {value: &#39;dummy&#39;}).value === &#39;Contractor&#39;&quot;
                    ),
                    textInput(&quot;NameContractor&quot;, &quot;Name of Contractor&quot;)
                )
                
            ))
    })
}

shinyApp(ui, server)

huangapple
  • 本文由 发表于 2023年6月29日 22:47:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76582185.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定