问题
Is it possible in shiny to reset radioButtons to an empty value (i.e. as if the radiobuttons would not have been clicked and the default value was empty (selected = ""))?
I tried reset("btn") with shinyjs() and updateRadioButtons(session, "btn",...). However, I only managed to reset the radiobuttons to a specific value (e.g. the first value in the list or another predefined value), but not to an empty value.
The reset to an empty value would make it possible to use a single set of radiobuttons for many repeated choices in a stated choice experiment (in combination with renderUI, where the radiobuttons are successively assinged to different variables.
回答1:
It's generally agreed upon (though of course nothing opinion-based is 100%) that radio buttons should not be used if you want the user to be able to revert back to the original no selection state. Even the documentation for radio buttons in shiny says this:
If you need to represent a "None selected" state, it's possible to default the radio buttons to have no options selected by using selected = character(0). However, this is not recommended, as it gives the user no way to return to that state once they've made a selection. Instead, consider having the first of your choices be c("None selected" = "").
If you look up discussions online you'll also see that it's commonly argued that a radio button with no initial selection is ok, with the caveat that often it means the user cannot go back to that state after making a selection because de-selecting is not really natively supported by radio buttons.
UPDATE
An update using updateRadioButtons()
may appear to work visually, but it doesn't actually reset the value to be unselected. The underlying value of the input is unchanged. Here's proof:
library(shiny)
ui <- fluidPage(
radioButtons("btn","Click Me",choices = c("Choice 1","Choice s"),selected = character(0)),
actionButton("clickMe","Click Me to Reset"),
actionButton("showValue", "Show value")
)
server <- function(input, output, session) {
observeEvent(input$clickMe,{
updateRadioButtons(session,"btn",choices = c("Choice 1","Choice s"),selected = character(0))
})
observeEvent(input$showValue, {
print(input$btn)
})
}
shinyApp(ui, server)
回答2:
Agree with @Dean Attali. But if it is absolutely needed (Not Recommended),
library(shiny)
ui <- fluidPage(
radioButtons("btn","Click Me",choices = c("Choice 1","Choice s"),selected = character(0)),
actionButton("clickMe","Click Me to Reset")
)
server <- function(input, output, session) {
observeEvent(input$clickMe,{
updateRadioButtons(session,"btn",choices = c("Choice 1","Choice s"),selected = character(0))
})
}
shinyApp(ui, server)
Consider using a checkbox gorup as an alternative?
Edit
library(shiny)
ui <- fluidPage(
radioButtons("btn","Click Me",choices = c("Choice 1","Choice s"),selected = character(0)),
actionButton("clickMe","Click Me to Reset"),
actionButton("showValue", "Show value")
)
server <- function(input, output, session) {
selected = reactiveVal(NULL)
observeEvent(input$clickMe,{
updateRadioButtons(session,"btn",choices = c("Choice 1","Choice s"),selected = character(0))
selected(NULL)
})
observeEvent(input$btn,{
selected(input$btn)
})
observeEvent(input$showValue, {
print(selected())
})
}
shinyApp(ui, server)
you can use a reactive val as a proxy. But we are getting into real hacky territory here.
Edit 2 Custom javascript solution
Here is the custom javascript solution discussed in the comments. In this solution if the user double clicks the radio button it gets unselected. You can double check the value though the button. Note you will not refer to input$btn
for the button value. A custom value is created with input$radio_click
.
library(shiny)
ui <- fluidPage(
tags$script(HTML("
window.onload = function(){
var btns = document.getElementById('btn');
btns_radio = btns.getElementsByTagName('input');
for(var i = 0; i < btns_radio.length; i++){
btns_radio[i].addEventListener('click',function(x){
Shiny.onInputChange('radio_click', this.value)
});
btns_radio[i].addEventListener('dblclick',function(x){
if(this.checked){
this.checked = false;
Shiny.onInputChange('radio_click', null)
}
})
}
}
")),
radioButtons("btn","Click Me",choices = c("Choice 1","Choice s"),selected = character(0)),
actionButton("showValue", "Show value")
)
server <- function(input, output, session) {
observeEvent(input$showValue, {
print(input$radio_click)
})
}
shinyApp(ui, server)
回答3:
@DeanAttali has the right idea.
resetRadioGroup = (formName, radioGroupName) => {
let form = document.forms[formName],
radioGroup = form && form.elements[radioGroupName],
selectedValue = radioGroup && radioGroup.value,
selectedRadio = form.querySelector(`[value=${selectedValue}]`);
if(selectedRadio){
selectedRadio.checked = undefined;
}
}
来源:https://stackoverflow.com/questions/54772944/reset-radiobuttons-in-shiny-to-empty-value