1
votes

Réinitialiser les boutons radio en brillant à la valeur vide

Est-il possible en brillant de réinitialiser radioButtons à une valeur vide (c'est-à-dire comme si les boutons radio n'auraient pas été cliqués et que la valeur par défaut était vide (selected = ""))?

J'ai essayé reset ("btn") avec shinyjs () et updateRadioButtons (session, "btn", ...). Cependant, je n'ai réussi à réinitialiser les boutons radio qu'à une valeur spécifique (par exemple, la première valeur de la liste ou une autre valeur prédéfinie), mais pas à une valeur vide.

La réinitialisation à une valeur vide permettrait d'utiliser un seul ensemble de boutons radio pour de nombreux choix répétés dans une expérience de choix déclaré (en combinaison avec renderUI, où les boutons radio sont successivement associés à différentes variables.


0 commentaires

4 Réponses :


2
votes

Il est généralement admis (bien que, bien sûr, rien de basé sur l'opinion ne soit à 100%) que les boutons radio ne doivent pas être utilisés si vous voulez que l'utilisateur puisse revenir à l'état d'origine sans sélection. Même la documentation des boutons radio en brillant dit ceci:

Si vous devez représenter un état "Aucun sélectionné", il est possible de définir par défaut les boutons radio pour qu'aucune option ne soit sélectionnée en utilisant selected = character (0). Cependant, cela n'est pas recommandé, car cela ne donne à l'utilisateur aucun moyen de revenir à cet état une fois qu'il a fait une sélection. Au lieu de cela, envisagez de faire en sorte que le premier de vos choix soit c ("Aucun sélectionné" = "").

Si vous recherchez des discussions en ligne, vous verrez également qu'il est communément admis qu'un bouton radio sans sélection initiale est correct, avec la mise en garde que souvent cela signifie que l'utilisateur ne peut pas revenir à cet état après avoir effectué une sélection car la désélection n'est pas vraiment prise en charge nativement par les boutons radio.

MISE À JOUR

Une mise à jour utilisant updateRadioButtons () peut sembler fonctionner visuellement, mais cela ne réinitialise pas réellement la valeur pour être désélectionnée. La valeur sous-jacente de l'entrée est inchangée. En voici la preuve:

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)


0 commentaires

0
votes

D'accord avec @Dean Attali. Mais si c'est absolument nécessaire (non recommandé),

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)

Pensez à utiliser une case à cocher gorup comme alternative?

Modifier

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)


11 commentaires

J'ai essayé selected = character (0) mais cela n'a pas résolu le problème. Le radiobutton semble vide, mais la variable d'entrée $ btn reste avec la valeur du dernier choix, de sorte que tous les choix en amont reçoivent par défaut la valeur du dernier choix.


Cela ne change pas réellement la valeur de l'entrée (cela ne fait que donner l'impression que l'apparence visuelle n'est pas cochée). Voir la mise à jour sur ma réponse pour preuve


@DeanAttali intéressant. Ouais, une option "Aucun sélectionné" semble être la seule façon d'aller ici.


Est-il possible de réinitialiser également la valeur de la variable d'entrée sous-jacente? J'ai essayé updateNumericInput (session, "btn", value = "") mais id n'a eu aucun effet. L'option «non sélectionné» fonctionne mais est moche. Les expériences de choix sont hautement standardisées et il est inhabituel (et plutôt déroutant) de proposer une option non sélectionnée.


@ReinhardHoessinger a mis à jour la réponse en utilisant un Val réactif comme proxy. Cela commence à devenir Hacky.


La solution reactiveVal fonctionnerait. Sinon, je suis assez certain que vous pourriez écrire du javascript personnalisé pour définir la valeur sur rien si vous étiez enclin à expérimenter avec cela.


@DeanAttali ouais j'ai commencé à essayer cela avec Shiny.onInputChange. Ce n'est pas trivial haha.


@Dean Attali a ajouté la solution JS personnalisée.


Je pensais davantage à l'utilisation de javascript pour décocher le bouton radio et définir la valeur de l'entrée sur vide :) Malheureusement, il n'y a tout simplement pas de solution élégante!


Enfin, j'ai pu résoudre le problème grâce au fait que, dans les expériences de choix déclarés, les répondants sont obligés de faire un choix dans chaque tâche répétée. J'ai donc introduit une variable de verrouillage, qui ne permet qu'une étape vers la tâche de choix suivante (en cliquant sur le bouton suivant), puis verrouille le bouton suivant (affiche un avertissement lorsque le bouton suivant est cliqué) jusqu'à ce que le répondant ait cliqué sur un bouton radio. Peut-être pas la solution la plus élégante, mais elle fait exactement ce que je veux.


En attendant, j'ai également vérifié la solution javascript de la 2ème édition. Cela fonctionne très bien (même sans shinyjs). C'est la solution élégante, merci. C'était la pièce manquante pour utiliser un seul ensemble de boutons radio pour des expériences de choix répétées.



0
votes

@DeanAttali a la bonne idée.

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;
    }
}


0 commentaires

0
votes

Une alternative pourrait être de générer un nouvel identifiant pour radioButtons () chaque fois que renderUI () génère un nouveau radioButtons () . De cette façon, vous obtenez toujours une valeur NULL au début.

shinyServer(function(input, output, session) {

radio_id <- "first_time"

  output$test <- rederUI({
    radio_id <<- paste0("but", gsub("\\s+|:", "", Sys.time()))
  
    radioButtons(
        inputId = radio_id,
        label = "Choose the correct answer",
        inline = TRUE,
        choices = t_item$choices, 
        selected = character(0)
    )
  
  })

}


0 commentaires