Shiny: réinitialiser la valeur de actionButton ?

Créé le 7 juin 2013  ·  71Commentaires  ·  Source: rstudio/shiny

un bouton d'action peut-il être réinitialisé à 0 dans server.R ?
disons que j'ai actionButton("b1","bouton1"). quel pourrait être le code pour réinitialiser le bouton d'action à 0 ?

Commentaire le plus utile

cela a-t-il déjà été résolu ou ont-ils simplement insisté sur le fait que personne n'en avait besoin? J'en ai besoin! :)

Tous les 71 commentaires

Non, pas pour le moment. Pouvez-vous nous expliquer pourquoi vous voulez cela ? Merci...

J'essayais de contourner le problème avec les boutons radio (et les boutons radio de mise à jour). Voici donc la logique. Nous avons 2 boutons disons b1 et b2. lorsqu'un bouton est enfoncé, il est augmenté de 1 dans le serveur. R nous rendons du texte pour cette action. après cela, le bouton doit être réinitialisé à 0 afin que si l'état d'un bouton est 1, il doit déclencher un rendu de texte, etc. . mais je pense que tu m'as donné la réponse. mais ce serait un bon ajout pour une amélioration du contrôle de l'interface utilisateur. Quelle est votre opinion ?

Ne pensez pas que la valeur de input$actionButtonId est significative, _sauf_ pour le cas particulier de 0, qui signifie "le bouton n'a pas encore été enfoncé". Dans tous les autres cas, vous devez simplement vous fier au fait que input$actionButtonId change et invalide votre expression réactive ou votre observateur. Si vous vous retrouvez à vérifier la valeur réelle de input$actionButtonId (autre que de tester pour 0), c'est un bon signe que vous devez probablement revoir l'utilisation isolate :

# Take an action when button is clicked
observe({
  if (input$actionButtonId == 0)
    return()
  isolate({
    # Your logic here
  })
})

# Render text when button is clicked
output$text <- renderText({
  if (input$actionButtonId == 0)
    return("")
  isolate({
    # Your logic here
  })
})

En fait, je pense que la réinitialisation est utile. J'ai une application qui contient plusieurs projets. Par exemple, chaque projet pourrait être un ensemble de données différent que j'analyse, donc lorsque je change de projet, je voudrais réinitialiser tous les boutons comme s'ils n'avaient jamais été pressés.

J'ai exactement le même problème où la réinitialisation des boutons d'action aiderait beaucoup. Un utilisateur peut changer d'emplacement/répertoires de travail où il peut analyser et créer des tracés pour différents ensembles de données. Pour tous ces différents ensembles de données, les mêmes boutons de tracé sont utilisés. Dès que vous changez de répertoire de travail, tous les scripts sont appelés car les boutons ont déjà été enfoncés.

Je suis également confronté à ce problème. J'ai deux boutons ajouter et effacer pour créer une requête. lorsque je sélectionne quelque chose et que je dis ajouter, ce terme doit être ajouté à la requête et si je clique sur le bouton Effacer, il doit effacer la requête. Je vérifie add_button> 0 maintenant, mais cela ne résoudra pas vraiment mon objectif, car lorsque je sélectionnerai autre chose après avoir cliqué sur le bouton Ajouter, il sera automatiquement ajouté à la requête. J'ai essayé de réinitialiser la valeur du bouton d'action mais je n'ai vraiment pas pu.

J'ai fait une solution de contournement étrange à la place, en utilisant une var que je remets à 0 dès que le bouton est enfoncé. J'utilise input$h5fileName pour que l'utilisateur puisse charger un autre fichier.

observe ({
    input$h5fileName
    counter_createTime_Plot <<- 0
})

lorsque j'appelle la fonction que je veux exécuter, je l'incrémente en veillant à ce qu'elle s'exécute chaque fois que j'appuie sur le bouton d'action.

observe({
    # increment the counter so i know it has been pressed
    if (counter_createTime_Plot == 0)
      counter_createTime_Plot <<- counter_createTime_Plot + 1

    #returning when the ui.R is opened the first time
    if (input$createTime_Plot == 0)
      return()

    # run the function because the button is clicked once after loading a new file
    else if (counter_createTime_Plot == 1) {
})

J'utilise la valeur de compteur 1 pour vérifier si le fichier est correct, en utilisant une instruction if suivante avec if (counter_createTime_Plot > 1) pour utiliser le même actionButton pour faire autre chose. Ce n'est pas une jolie solution mais pour l'instant ça marche comme je le veux. Pouvoir réinitialiser serait encore bien mieux.

Je ne pense toujours pas que tu en aies besoin. Si votre logique d'ajout est entourée d'isolat, vous ne devriez pas avoir ce problème. Si je me trompe, faites le moi savoir.

dans le cas de sarvagna, très probablement oui, car je soupçonne que son champ de saisie se trouve dans le même observateur que les deux actionButtons (peut-être partager le code ?). Dans mon cas, cependant, j'ai un bouton qui doit vérifier l'entrée de données lorsqu'il est cliqué pour la première fois, lorsque vous cliquez dessus pour la deuxième fois, il ne doit pas vérifier l'entrée de données mais créer un tracé à la place. Un troisième clic ne ferait rien puisque les données sont validées et le tracé a été fait.

Cependant, l'utilisateur peut également changer de fichier et dès qu'il le fait, le bouton de tracé devient inutile. Dans cette situation, ce serait parfait si je pouvais simplement réinitialiser le bouton d'action à la place lorsqu'un fichier différent est chargé. Maintenant, je dois garder une trace du nombre de fois qu'il est cliqué avec une variable de compteur externe.

Voici mon code, j'ai essayé d'utiliser la logique que vous avez mentionnée. cela fonctionne bien la première fois que je clique sur le bouton Ajouter ou Effacer. mais après ça les boutons ne servent à rien.

observe({
 if (input$add_button == 0)
   return()
   isolate({
  selected_term_ids<-c(input$thti,input$select_child_terms)
  if((!is.null(selected_term_ids)) & length(selected_term_ids)>0){
    onto <- input$search_option
  selected_terms <-    get_onto_terms_by_ids(paste0(selected_term_ids,collapse=","))
 } 
 if(!is.null(DisplayString$names)){
   DisplayString$names<-unique(append(DisplayString$names,selected_terms$term))
   QueryString$names<-unique(append(QueryString$names,selected_term_ids))
 }
 else{
   DisplayString$names<-selected_terms$term
   QueryString$names<-selected_term_ids
 }
 output$dynamic_value <- renderText({
   paste0(DisplayString$names, collapse=",")
 })
  })
if(input$clear_button == 0)
  return()
  isolate({
 DisplayString$names<- NULL
 QueryString$names <- NULL
 output$dynamic_value <- renderText({DisplayString$names})
})
 })

Essayez d'utiliser deux observateurs, un pour chaque bouton. De plus, que sont DisplayString et QueryString ? Juste des listes normales ou des objets reactiveValues ?

ce sont des objets reactiveValues. J'utiliserai la chaîne d'affichage dans verbatimtextoutput et la chaîne de requête dans la fonction de requête db plus bas dans le code

Dans ce cas, output$dynamic_value n'a besoin d'être assigné qu'une seule fois, en dehors de tout observateur.

Eh bien, j'ai fait quelque chose comme ça et ça semble fonctionner pour l'instant.

#Build query
  DisplayString <- reactiveValues()
  QueryString <- reactiveValues()

  observe({
    if (input$add_button > 0){
      isolate({
        selected_term_ids<-c(input$thti,input$select_child_terms)
        if((!is.null(selected_term_ids)) & length(selected_term_ids)>0){
          onto <- input$search_option
        selected_terms <- get_onto_terms_by_ids(paste0(selected_term_ids,collapse=","))
        } 
        if(!is.null(DisplayString$names)){
          DisplayString$names<-unique(append(DisplayString$names,selected_terms$term))
          QueryString$names<-unique(append(QueryString$names,selected_term_ids))
        }
        else{
          DisplayString$names<-selected_terms$term
          QueryString$names<-selected_term_ids
        }
      })
    }
#Clear selection
if(input$clear_button >= input$add_button){
  isolate({
    DisplayString$names<- NULL
    QueryString$names <- NULL
  })
}
  })

  #Show selected terms
  output$dynamic_value <- renderText({
    paste0(DisplayString$names, collapse=",")
  })

J'aimerais vraiment pouvoir réinitialiser un actionButton à 0.

@ sharko666 Faites-moi savoir si vous avez un exemple simple de la raison pour laquelle vous en avez besoin. Je suis totalement ouvert à être convaincu, mais je n'ai vu jusqu'à présent aucun scénario qui n'ait été mieux géré en utilisant les idiomes que nous avons déjà établis.

Joe, tu m'as envoyé ça par erreur ? Je ne suis pas sharko666.

Le lundi 13 octobre 2014 à 11h29, Joe Cheng [email protected]
a écrit:

@ sharko666 https://github.com/sharko666 Faites-moi savoir si vous avez un
exemple simple de pourquoi vous en avez besoin. Je suis totalement ouvert à être convaincu
mais je n'ai vu aucun scénario jusqu'à présent qui n'ait pas été mieux géré en utilisant le
idiomes que nous avons déjà établis.


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment -58934438.

Marc-david Cohen | Directeur scientifique | +1.415.205.6295 |
www.aktana.com

_Le pouvoir de plusieurs, la concentration d'un_

@Marccohen Vous avez probablement reçu une copie du message parce que vous regardez le référentiel brillant sur github.

Salut Joe,
Je travaille sur une application qui prend une URL dans un champ de texte et charge des ensembles de données à partir d'une URL. Cela fonctionne bien tant que l'utilisateur copie et colle l'URL dans le champ de texte. S'il y a une erreur dans l'URL ou si elle est saisie, shiny essaie constamment de charger des données à partir d'une URL inachevée. C'est pourquoi j'ai pensé ajouter un bouton d'envoi. Cela a amélioré les choses car maintenant l'URL peut également être saisie car rien ne se passe tant que le bouton est enfoncé. Le nouveau problème survient lorsqu'une autre URL après la première est saisie. Le compteur est déjà supérieur à 0, donc le bouton est marqué comme enfoncé. Cela ne fonctionne donc que pour la première fois. Ce problème aurait été facilement résolu s'il y avait eu un moyen de réinitialiser le compteur dans la partie logique lorsque l'ensemble de données est chargé ou qu'une erreur appropriée (si l'URL est toujours erronée) est détectée.

Maintenant, j'ai trouvé une solution mais ce n'est peut-être pas la solution car le brillant est censé fonctionner. J'ai une variable globale définie dans la fonction reactiveValues ​​appelée actionCounter. Chaque fois que vous appuyez sur le bouton, le compteur de bouton augmente et est supérieur à actionCounter. Dans la logique, le compteur d'action est défini sur le compteur de boutons. Maintenant, je teste uniquement si actionCounter est inférieur à buttonCounter. Voir le code ci-dessous.

serveur.R

vars = reactiveValues(actionCounter=0)

à l'intérieur de l'observateur pour le champ de texte

url = input$URL_input
if(!is.null(input$submit_URL)){
if(input$submit_URL>vars$actionCounter&url !=""){
vars$actionCounter=input$submit_URL
# essayez de charger les données
}
}

Donc il y a une solution relativement facile mais s'il y avait eu la possibilité de réinitialiser le compteur des boutons cela aurait été plus simple et plus facile à comprendre.

Salutations

Christophe


De : Marc Cohen [[email protected]]
Envoyé : mardi 14 octobre 2014 7:37
À : rstudio/brillant
Copie : Christoph Knapp
Objet : Re : [brillant] réinitialiser la valeur de actionButton ? (#167)

Joe, tu m'as envoyé ça par erreur ? Je ne suis pas sharko666.

Le lundi 13 octobre 2014 à 11h29, Joe Cheng [email protected]
a écrit:

@ sharko666 https://github.com/sharko666 Faites-moi savoir si vous avez un
exemple simple de pourquoi vous en avez besoin. Je suis totalement ouvert à être convaincu
mais je n'ai vu aucun scénario jusqu'à présent qui n'ait pas été mieux géré en utilisant le
idiomes que nous avons déjà établis.


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment -58934438.

Marc-david Cohen | Directeur scientifique | +1.415.205.6295 |
www.aktana.com

_Le pouvoir de plusieurs, la concentration d'un_


Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps://github.com/rstudio/shiny/issues/167#issuecomment -58935448.

Merci pour les commentaires. Voici la manière idiomatique de gérer une telle situation :

url <- reactive({
  if (input$submit_URL == 0) {
    return(NULL)
  }
  isolate(input$URL_input)
})

Ensuite, partout où vous souhaitez accéder à l'URL, utilisez url() .

C'est un grief de longue date contre Shiny que nous n'ayons pas de fonctions d'emballage pour cet idiome.

@ sharko666 Je viens de fusionner une demande d'extraction de très longue date dans le maître. Avec ce changement, vous pouvez maintenant faire ceci à la place :

url <- reactive({
  eventFilter(input$submit_URL, input$URL_input)
})

Cela signifie essentiellement "la valeur de url n'est rien (NULL) au début, mais chaque fois que vous cliquez input$submit_URL , réglez-le sur la valeur actuelle de input$URL_input ".

Il existe également une fonction complémentaire observeEvent :

observeEvent(input$submit_URL, function() {
  # Do something involving input$URL_input
})

La partie "faire quelque chose" du code sera exécutée quand et seulement quand le bouton sera cliqué.

@ jcheng5 Je viens d'utiliser la nouvelle version de Shiny - 10.2.9 pour la nouvelle fonction observeEvent. Cela fonctionne très bien sur ma version de bureau de R studio, mais j'essaie de l'exécuter à l'aide d'une installation portable R et Chrome à partir d'un lecteur flash. Cela a bien fonctionné avec Shiny 10.2.1 car j'ai pu trouver un zip qui fonctionnait pour Shiny 10.2.1. J'ai essayé d'aller sur github, mais je ne sais pas comment je peux trouver (ou créer) un zip 10.2.9 qui fonctionnera pour une installation portable (32 bits) de R. Si vous pouviez pointer dans la bonne direction, ce serait très appréciée. Merci :)

@dakshvarma Y a-t-il une raison pour laquelle devtools :: install_github` ne fonctionnerait pas avec votre portable R ?

@ jcheng5 Ça marche enfin ! devtools::install_github l'installe en créant un dossier local. L'astuce consiste à compresser le dossier local, à installer un package à partir du zip dans l'installation portable (avec le zip dans le même dossier que portable R). Merci pour ton aide!

j'ai le cas suivant :
2 boutons d'action (Générer et Réinitialiser) qui doivent être utilisés sous UN seul renderPlot.
Comment gérer cette situation ? Apprécier ton aide

output$Result <- renderPlot({
  if(input$GEN_button == 0){
    # mylogic
  }
  else if(input$RES_button == 0){
    # mylogic
  }
  else {
    # mylogic
  }
})  

Que fait Reset, l'effacer ? Quel devrait être l'état initial de l'intrigue
être - doit-il être généré lors du premier démarrage de l'application, ou doit-il être
Vide?

Le mardi 18 novembre 2014 à 8h37, Hratch [email protected] a écrit :

j'ai le cas suivant :
2 boutons d'action (Générer et Réinitialiser) qui doivent être utilisés sous UN
renderPlot.
Comment gérer cette situation ? Apprécier ton aide

output$Result <- renderPlot({
if(input$GEN_button == 0){
# malogique
}
sinon si si(entrée$RES_bouton == 0){
# malogique
}
autre {
# malogique
}
})


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment -63500459.

Reset remet la valeur de la matrice à tracer à une valeur initiale.
L'état initial (Exécution initiale) doit afficher le tracé de la matrice créée dans la logique.
Si le bouton Générer est cliqué, une nouvelle matrice sera générée et tracée.

Cela signifie que la matrice peut également être calculée en dehors du renderPlot, n'est-ce pas ?

Dans ce cas, il semble que les deux Générer à la réinitialisation ne devraient pas affecter le
tracer directement, mais une valeur matricielle.

initialMatrixValue <- ...
shinyServer(function(input, output, session) {
  values <- reactiveValues(matrix = initialMatrixValue)
  observe({
    if (input$GEN_button == 0)
      return()
    values$matrix <- ... # Generate the matrix here
  })
  observe({
    if (input$RES_button == 0)
      return()
    values$matrix <- initialMatrixValue
  })
  output$Result <- renderPlot({
    plot(values$matrix) # or whatever
  })
})

Merci pour votre réponse/solution rapide, vous êtes super.

J'essaie de faire quelque chose de similaire et j'ai plusieurs problèmes:

  1. J'accepte une phrase, je traite la phrase et prédis un mot, j'ajoute le mot prédit dans l'entrée. Mais cela provoque une boucle infinie. Y'a t'il un moyen d'arranger cela?
  2. Ensuite, j'ai créé une zone de texte pour le mot prédit, puis j'ai ajouté un bouton "Accepter". Si l'utilisateur appuie sur Accepter, le mot est ajouté à la phrase existante. Cependant, je n'arrive pas à faire fonctionner cela. Le code est ci-dessous :

ui.R :
textInput("mot", "Phrase", valeur=""),
textInput("predictedword", "Prochain mot :", value=""),
actionButton("accepter", "Accepter")

serveur.R
serveurbrillant(
fonction (entrée, sortie, session) {
observer ({
si (entrée$accepter > 0) {
prédit <- coller (entrée $ mot, entrée $ mot prédit)
updateTextInput (session, "mot", valeur = prédit)
}
autre {
retourner()
}
})

observe({
  nextword <- toString(predict(input$word,all.gram,4))
  updateTextInput(session, "predictedword", value = nextword)
})  

})

La boucle infinie peut être corrigée en ajoutant la fonction en gras :

si (entrée$accepter > 0) {

  • isoler({*
    prédit <- coller (entrée $ mot, entrée $ mot suivant)
    updateTextInput (session, "mot", valeur = prédit)
  • })*
    }

C'est presque toujours le modèle que vous voulez suivre lors de l'utilisation
bouton d'action. En fait, nous avons des fonctionnalités à venir dans Shiny qui
enveloppez ce modèle pour vous afin qu'il soit plus naturel de suivre.

Voir http://shiny.rstudio.com/articles/isolation.html pour plus de détails.

Le jeudi 20 novembre 2014 à 11h27, Shanthi [email protected] a écrit :

J'essaie de faire quelque chose de similaire et j'ai plusieurs problèmes:

  1. J'accepte une phrase, je traite la phrase et prédis un mot, j'ajoute le
    mot prédit dans l'entrée. Mais cela provoque une boucle infinie. Est
    il y a un moyen de réparer ça ?
  2. Ensuite, j'ai créé une zone de texte pour le mot prédit, puis ajouté un bouton
    "J'accepte". Si l'utilisateur appuie sur Accepter, le mot est ajouté à l'existant
    phrase. Cependant, je n'arrive pas à faire fonctionner cela.

ui.R :
textInput("mot", "Phrase", valeur=""),
textInput("predictedword", "Prochain mot :", value=""),
actionButton("accepter", "Accepter")

serveur.R
serveurbrillant(
fonction (entrée, sortie, session) {
observer ({
si (entrée$accepter > 0) {
prédit <- coller (entrée $ mot, entrée $ mot suivant)
updateTextInput (session, "mot", valeur = prédit)
}
autre {
retourner()
}
})

observer({
mot suivant <- toString(predict(input$word,all.gram,4))
updateTextInput (session, "mot prédit", valeur = mot suivant)
})

})


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment -63864397.

Cool, ça a très bien fonctionné. Merci pour votre réponse rapide.

Est-il possible de placer le curseur à la fin du texte dans le scénario ci-dessus ? En gros, lorsque l'utilisateur clique sur "Accepter", j'ajoute le texte au texte saisi mais je souhaite placer le curseur à la fin.

Cela doit être fait avec JS. Essayez d'inclure ceci dans votre interface utilisateur.

balises$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var entrée = $('#mot');
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
"))

Juste après avoir appelé updateTextInput(session, "word", ...), vous devez ajouter :
session$sendCustomMessage("cursorEnd", NULL)

Le jeudi 20 novembre 2014 à 12h55, Shanthi [email protected] a écrit :

Est-il possible de placer le curseur à la fin du texte dans ce qui précède
scénario? En gros, lorsque l'utilisateur clique sur "Accepter", j'ajoute le texte au
saisir du texte mais je veux placer le curseur à la fin.


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment -63878009.

Joe - cela ne fait rien. Mes ui.R et server.R sont ci-dessous :
bibliothèque (brillant)
bibliothèque(stringi)
bibliothèque (data.table)

brillantUI(fluidePage(
titlePanel("TextPredictor"),
lignefluide(
colonne(6, wellPanel(
textInput("mot", "Phrase", valeur=""),
tags$style(type='text/css', "#word { largeur : 300px ; }"),
balises$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var entrée = $('#mot');
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
")) ,
actionButton("effacer", "Effacer"),
textInput("predictedword", "Prochain mot :", value=""),
actionButton("accepter", "Accepter")
))
)))

serveur.R
serveurbrillant(
fonction (entrée, sortie, session) {
observer ({
si (entrée$accepter > 0) {
isoler({
phrase <- nettoyer (entrée $ mot)
prédit <- coller(phrase, input$predictedword)
updateTextInput (session, "mot", valeur = prédit)
session$sendCustomMessage("cursorEnd", NULL)
})
}
})

observe ({
  if (input$clear > 0) {
    isolate({
      updateTextInput(session, "word", value = "")
    })
  }
})

observe({
  phrase <- clean(input$word)
  nextword <- toString(predict(phrase,all.gram,4))
  updateTextInput(session, "predictedword", value = nextword)
})  

})

Désolé, deux erreurs :

Shiny.addCustomMessageHandler('cursorEnd', function() {
devrait être
Shiny.addCustomMessageHandler('cursorEnd', function(_message_) {

et

session$sendCustomMessage("cursorEnd", NULL)
devrait être
session$sendCustomMessage("cursorEnd", TRUE)

Le jeudi 20 novembre 2014 à 14h50, Shanthi [email protected] a écrit :

Joe - cela ne fait rien. Mes ui.R et server.R sont ci-dessous :
bibliothèque (brillant)
bibliothèque(stringi)
bibliothèque (data.table)

brillantUI(fluidePage(
titlePanel("TextPredictor"),
lignefluide(
colonne(6, wellPanel(

textInput("mot", "Phrase", valeur=""),
tags$style(type='text/css', "#word { largeur : 300px ; }"),
balises$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var entrée = $('#mot');
alerte (entrée)
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
")) ,
actionButton("effacer", "Effacer"),
textInput("predictedword", "Prochain mot :", value=""),
actionButton("accepter", "Accepter")
))
)))

serveur.R
serveurbrillant(
fonction (entrée, sortie, session) {
observer ({
si (entrée$accepter > 0) {
isoler({
phrase <- nettoyer (entrée $ mot)
prédit <- coller(phrase, input$predictedword)
updateTextInput (session, "mot", valeur = prédit)
session$sendCustomMessage("cursorEnd", NULL)
})
}
})

observer ({
si (entrée$clair > 0) {
isoler({
updateTextInput(session, "mot", valeur = "")
})
}
})

observer({
phrase <- nettoyer (entrée $ mot)
mot suivant <- toString(predict(phrase,all.gram,4))
updateTextInput (session, "mot prédit", valeur = mot suivant)
})

})


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment -63894797.

Très bonne solution, merci encore. Je ne savais même pas que ces méthodes existaient dans Shiny.

J'ai un nouveau problème. Je peux ajouter le texte et définir le curseur, cependant, le curseur n'est pas visible. Je vois toujours la première partie du texte et le texte ne défile pas vers la droite.

J'ai converti du texte en zone de texte et je vois le même problème. Comment puis-je mettre en évidence la fin de la zone de texte ? Merci

J'ai l'impression qu'un cas simple a été négligé (et pardonnez-moi si j'ai en quelque sorte manqué cet exemple dans le fil ci-dessus). Il est très courant d'avoir un ensemble de cases à cocher avec un bouton pour tout cocher et un autre pour tout décocher. Par exemple, le code souhaité de server.R ci-dessous. Bien que je puisse concevoir plusieurs façons de contourner ce problème, cela ne signifie pas que vous ne devriez pas pouvoir réinitialiser à 0. La raison pour laquelle le code ci-dessous ne fonctionne pas est qu'après avoir sélectionné et désélectionné une fois, les deux valeurs du bouton d'action d'entrée sont supérieurs à 0. Je ne tire rien de significatif du compteur d'incréments autre que "la valeur spéciale de 0" comme indiqué ci-dessus. Des réflexions sur cet exemple ?

observer({
si (input$uncheckAll > 0 ) {
updateCheckboxGroupInput(session = session, inputId = "test", choix = c(1,2,3), sélectionné = NULL)
}
si (entrée$checkAll > 0 ) {
updateCheckboxGroupInput(session = session, inputId = "test", choix = c(1,2,3), sélectionné = c(1,2,3))
}
})

Ceux-ci doivent simplement être deux observateurs distincts.

observe({
  if (input$uncheckAll > 0 ) {
    updateCheckboxGroupInput(session = session, inputId = "test", choices = c(1,2,3), selected = NULL)
  }
})
observe({
  if (input$checkAll > 0 ) {
    updateCheckboxGroupInput(session = session, inputId = "test", choices = c(1,2,3), selected = c(1,2,3))
  }
})

En fait, avec les versions récentes de Shiny, il est plus agréable d'utiliser observeEvent, et vous n'avez pas non plus besoin de fournir les choix s'ils ne changent pas :

observeEvent(input$uncheckAll, {
  updateCheckboxGroupInput(session, "test", selected = NULL)
})
observeEvent(input$checkAll, {
  updateCheckboxGroupInput(session, "test", selected = c(1,2,3))
})

Merci beaucoup, cela a du sens et je me corrige. Je ne comprends toujours pas très bien la résistance à ne pas pouvoir réinitialiser à zéro - cela ne semble pas promouvoir de manière inhérente de mauvaises pratiques de codage, et ce n'est pas parce que quelque chose peut être fait d'une manière qu'il n'y a peut-être pas de meilleure ou de manière plus intuitive. Quoi qu'il en soit, vous avez trouvé des solutions élégantes pour la plupart des problèmes ici, donc pour l'instant, cela suffira certainement. Aussi, merci pour les conseils sur observeEvent(). Je n'étais même pas au courant de cette nouvelle construction (je suis relativement novice en matière de brillant, et peu d'exemples de la galerie semblent utiliser certaines des fonctionnalités les plus récentes que je rencontre).

Je ne comprends toujours pas très bien la résistance à ne pas pouvoir réinitialiser à zéro - cela ne semble pas promouvoir de manière inhérente de mauvaises pratiques de codage

Cela favorise absolument, positivement, les mauvaises pratiques de codage. Regardez simplement tous les exemples de code dans ce fil (sans faute des utilisateurs, bien sûr - nous n'avons tout simplement pas fait un assez bon travail avec l'éducation). Le bouton d'action sur lequel vous cliquez doit être considéré comme un événement discret et non comme une valeur. La valeur spéciale 0 est juste une solution de contournement pour empêcher le code de penser que le bouton est cliqué au démarrage. C'est _le fait qu'un nombre a changé_ qui est le signal pertinent ici, pas _la valeur que le nombre se trouve être_.

Le système de réactivité de Shiny n'a pas été conçu pour la programmation impérative - et appuyer sur un bouton est, par nature, impératif. C'est un pur coup de chance que j'ai trouvé l'idiome observer/isoler qui permet aux actionButtons de fonctionner si bien. C'est un modèle très étroit qui a des applications très larges ; si vous restez dans le schéma, vous pouvez accomplir presque n'importe quoi en toute sécurité. Si vous vous écartez du modèle, votre programme est soudainement très difficile à raisonner ET n'accomplit probablement pas non plus ce que vous vouliez à l'origine.

Je pense qu'une partie de la raison est que les exemples d'observation/d'isolement ne ressemblent à rien de particulièrement spécial par rapport à d'autres codes réactifs. J'espère qu'observeEvent aidera à rendre l'intention plus claire et à rendre moins tentant d'en abuser.

Je suis toujours en désaccord avec cette prémisse. Il y a une différence entre la promotion de mauvaises pratiques de codage et les personnes qui utilisent le code de la mauvaise manière. Presque toutes les constructions de code peuvent être utilisées de manière inappropriée. Je pense que la racine de ce désaccord peut être la mise en œuvre du compteur pour l'actionButton, qui, je pourrais dire, n'est pas intuitive sur la base de nombreux exemples plus anciens que j'ai trouvés en utilisant observe. J'accorderai volontiers que l'interface pour observeEvent est beaucoup plus propre et obscurcira naturellement la valeur associée à actionButton. En tout cas je vous remercie infiniment pour votre aide. Si vous souhaitez poursuivre la conversation sur la promotion des mauvaises pratiques de codage, n'hésitez pas à m'envoyer un e-mail car je ne veux pas que ce fil de discussion s'éloigne trop du sujet. Bien sûr, si cela concerne les exemples et les cas d'utilisation, postez définitivement ici. Merci encore.

remarque rapide. Dans mon exemple uncheckAll, j'ai utilisé selected = NULL dans updateCheckboxGroupInput. Selon la documentation de cette méthode, tous les arguments avec une valeur NULL seront ignorés. Par conséquent, pour ceux qui regardent cet exemple, vous devez utiliser selected = c('') ou un équivalent similaire.

Salut, je pense qu'il y a actuellement un problème avec l'approche : si vous supprimez et ajoutez à nouveau le bouton avec le même ID, le input$ID peut toujours exister et n'est donc plus nul, donc la fonction est exécutée immédiatement lorsque ajouté, j'ai contourné ce problème en étendant la fonction observeEvent de la manière suivante (en un mot : j'obtiens d'abord l'ancienne valeur, puis je compare avec le nouvel événement) :

observeEvent2 <- function (eventExpr, handlerExpr, event.env = parent.frame(),
          event.quoted = FALSE, handler.env = parent.frame(), handler.quoted = FALSE,
          label = NULL, suspended = FALSE, priority = 0, domain = getDefaultReactiveDomain(),
          autoDestroy = TRUE, ignoreNULL = TRUE)
{
  eventFunc <- exprToFunction(eventExpr, event.env, event.quoted)
  if (is.null(label))
    label <- sprintf("observeEvent(%s)", paste(deparse(body(eventFunc)),
                                               collapse = "\n"))
  handlerFunc <- exprToFunction(handlerExpr, handler.env,
                                handler.quoted)

  oldValue <- isolate(eventFunc())

  invisible(observe({
    e <- eventFunc()
    if (ignoreNULL && (isNullEvent(e) || (!is.null(oldValue) && e == oldValue))) {
      return()
    }
    isolate(handlerFunc())
  }, label = label, suspended = suspended, priority = priority,
  domain = domain, autoDestroy = TRUE))
}

Ce n'est pas encore parfait mais fonctionne beaucoup mieux.

Moi aussi, je me retrouve à vouloir réinitialiser un bouton d'action. Je ne trouve pas la fonctionnalité suivante dans le fil jusqu'à présent, donc je vais l'essayer pour Joe...

Cela a à voir avec l'utilisation d'un panneau conditionnel qui examine une valeur de bouton d'action pour sa condition (c'est dans ui.R, _not_ server.R).

Dans un sidePanel j'ai quelque chose comme:

sidePanel(
...
actionButton(doit,"Configure this variable")
...
)

puis dans un panneau principal j'ai quelque chose comme

mainPanel(
   ...
   # for action button not pushed:
   conditionalPanel(condition="input.doit == 0 & input.tabs==...",
                                ...),
   ...
   # for action button pushed:
   conditionalPanel(condition="input.doit > 0 & input.tabs==...",
                                ...),

Maintenant, à un moment donné (peut-être déclenché par un autre bouton d'action, je voudrais réinitialiser input.doit et réafficher le premier panneau conditionnel, demander à l'utilisateur de re-spécifier les entrées là-bas, etc. Il semble qu'il serait assez naturel d'avoir quelque chose comme updateActionButton() dans server.R pour me ramener à mon premier panneau conditionnel.

Je serais très heureux d'entendre la manière "juste et appropriée" de le faire, étant donné que updateActionButton() n'existe pas.

Pour obtenir un bouton d'action 0 / 1 sans réinitialiser :

attr(input, "readonly") <- FALSE
input$ActionButtonMemory <- 0
observe({
  if(length(input$ActionButton)>0){
  if((input$ActionButton-input$ActionButtonMemory)>0){
    input$ActionButtonMemory<- input$ActionButton # Equalize
    # DO YOUR THING HERE
  }}
})

Je suis tombé sur ce problème, alors que je cherchais un moyen d'écrire un gestionnaire unique capable de répondre à un grand nombre de boutons d'action individuels (changeant dynamiquement). Voici un exemple de ce que j'essayais de faire :

save_settings <- function()
  {
    xs <- seq(1,100,by=1)
    result<-lapply(xs,function(x){
      observeEvent(input[[paste0(x,"_save")]], {
            if(!(input[[paste0(x,"_save")]]==0)){
        # Save something for this value of x.
        #input[[paste0(x,"_save")]] <- 0 # Could be a nice place to be able to reset to 0.
            }
          }
        }
        message(paste0(x,"_save: ",input[[paste0(x,"_save")]]))
      })
      input[[paste0(x,"_save")]]
    })
    return(result)
  }
})

Je pourrais voir que la "réinitialisation" à zéro est utile dans ce cas, mais il existe peut-être une meilleure façon de procéder.
Est-ce que quelqu'un a fait quelque chose de similaire?

@mikebirdgeneau Ce n'est absolument pas nécessaire dans ce cas. C'est tout ce que vous devez faire :

save_settings <- function() {
  xs <- seq(1,100,by=1)
  lapply(xs,function(x){
    observeEvent(input[[paste0(x,"_save")]], {
      # Save something for this value of x.
    })
  })
}

@ jcheng5 merci - je vais essayer! Appréciez la réponse rapide. Acclamations.

Je peux voir un argument pour réinitialiser un actionButton que je n'ai pas vu mentionné ici (excuses si cela a été mentionné, et je l'ai manqué). J'aimerais pouvoir copier l'URL du navigateur dans lequel mon application brillante s'exécute, l'envoyer à quelqu'un d'autre et lui permettre de charger la même page avec toutes les entrées automatiquement renseignées à partir de l'URL. Cependant, je ne souhaite pas que les actions exécutées par un actionButton s'exécutent automatiquement. (Un exemple de ceci pourrait être une page utilisée pour visualiser des données, avec un actionButton qui déclenchera l'écriture de ces données dans un fichier particulier. Je veux pouvoir envoyer une visualisation de ces données à quelqu'un en lui envoyant l'URL à ma page, mais ils ne voudront peut-être pas l'écrire dans un fichier lors du chargement de la page).

Par défaut, shiny peut enregistrer/charger toutes ses variables d'entrée vers/depuis l'URL, ce qui est très bien la plupart du temps, mais peut causer des problèmes lorsqu'il charge des actionButtons avec des valeurs > 0. Dans ces cas, comme dans l'exemple ci-dessus, il pensera que l'utilisateur a cliqué sur l'actionButton alors qu'en réalité il ne l'a pas encore fait.

C'est un cas dans lequel la valeur de actionButton n'a pas d'importance, mais le fait qu'elle ne soit pas nulle est important. Merci pour ton aide!

Par défaut, shiny peut enregistrer/charger toutes ses variables d'entrée vers/depuis l'URL

Ce n'est pas une fonctionnalité intégrée de Shiny ; existe-t-il un package spécifique que vous utilisez pour vous offrir cette fonctionnalité ?

Vous avez raison - cela fait partie d'un package séparé (qui n'est pas encore accessible au public). Merci pour votre réponse rapide.

@nhpackard est-ce que shinyjs vous aide à accomplir ce dont vous avez besoin ? Voici un exemple minimal de toggle :

library(shiny);library(shinyjs)

shinyApp(
  ui = fluidPage(
    sidebarLayout(
      sidebarPanel(
        actionButton("showPanel","Show Panel!")
      ),
      mainPanel(
        useShinyjs(),
        absolutePanel(id = "panel", class = "panel panel-default",
                      style = "z-index:100; display: none;",

                      div(style="margin:10px;",
                          h3("Hello World")
                      )
        )
      )
    )
  ),
  server = function(input, output) {

    observeEvent(input$showPanel,{
      toggle("panel")
    }) 

  }
)

Il n'utilise pas conditionalPanel mais je pense qu'il est plus propre de garder la logique côté serveur. En appuyant sur un bouton, vous pouvez avoir updateX pour chacune des entrées, et exécuter l'analyse, etc.

Salut Joe,

J'ai bloqué le problème similaire lié à la réinitialisation du bouton d'action. Mon problème est

Sur l'interface utilisateur : j'ai 1 glisser vers le bas qui contient 2 valeurs "Suntrust Bank" et "Huntington Bank". Et en dessous, j'ai 3 boutons d'action pour 3 tâches : traiter les données, télécharger les données traitées et télécharger les données traitées.

Lorsque je sélectionne Suntrust pour la première fois, les trois boutons d'action ci-dessous ne sont pas exécutés à moins que je ne les appuie. Cependant, chaque fois que je sélectionne Huntington, les 3 boutons ci-dessous s'exécutent automatiquement (les boutons n'ont pas été enfoncés).

Pourriez-vous s'il vous plaît m'aider à résoudre ce problème? Idéalement, j'aimerais avoir : lorsque je change SunTrust en Huntington ou encore Huntington en SunTrust, les 3 boutons ci-dessous (processus, téléchargement et téléchargement) ne doivent pas fonctionner tant que je n'appuie pas dessus.

Merci d'avance !!

Comme ça:

observeEvent(input$process, {
# code de traitement ici
})
observeEvent(input$download, {
# télécharger le code ici
})
observeEvent(input$upload, {
# télécharger le code ici
})

Le mar. 26 janvier 2016 à 10 h 18 abhijeetgosavi [email protected]
a écrit:

Salut Joe,

Je suis resté autour du problème similaire lié à la réinitialisation de l'action
bouton. Mon problème est

Sur UI : j'ai 1 drag down qui contient 2 valeurs "Suntrust Bank" et
"Banque Huntington". Et en dessous, j'ai 3 boutons d'action pour 3 tâches :
traiter les données, télécharger les données traitées et télécharger les données traitées.

Lorsque je sélectionne Suntrust pour la première fois, les trois boutons d'action ci-dessous ne sont pas
exécuté à moins que je les appuie. Cependant, chaque fois que je sélectionne Huntington,
ci-dessous 3 boutons exécutés automatiquement (les boutons n'ont pas été pressés) .

Pourriez-vous s'il vous plaît m'aider à résoudre ce problème? Idéalement, j'aimerais
avoir : quand je change SunTrust en Huntington ou encore Huntington en
SunTrust, les 3 boutons ci-dessous (process, download et upload) ne doivent pas
travailler à moins que et jusqu'à ce que je les appuie.

Merci d'avance !!


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment -175154688.

Oui, exactement. Permettez-moi de coller mon code server.r ici
Serveur.r

library(data.table)
library(shiny)
library(stats)

shinyServer(function(input, output, session) {

  datasetInput <- reactive({
    switch(input$Select,
      "SunHE" = heloc.comp.rate, 
      "HunHE" = heloc.comp.rate1
    )
  })

  observeEvent(input$goButton, {
    output$MyData <- renderDataTable({
      datasetInput()
    })
  })

  observeEvent(input$Click, {
    output$fill <- renderUI({ 
      write.csv(datasetInput(), file.loc,row.names=FALSE)
    }) 
  })

  observeEvent(input$Submit, {
    output$fill <- renderUI({ 
      write.csv(datasetInput(), Up.file.loc,row.names=FALSE)
    })  
  })
})

ui.r

brillantUI(fluidePage(
titlePanel("Générer le fichier IG tarif concurrent"),

sidebarLayout(

sidebarPanel(

 selectInput("Select","Select Customer:", 
                    list(SunHE = "SunHE", HunHE  = "HunHE")
                    ) ,

 actionButton("goButton", "Generate GI File")  ,

 actionButton("Click", "Download GI File")  ,

 actionButton("Submit", "Upload GI File"),


uiOutput("fill") ,

uiOutput("Upload")
         )

    ,

mainPanel(
  h3(textOutput("caption")),
  dataTableOutput("MyData")
         )
         )

))

Lorsque je change de banque de Suntrust à Huntington à partir de Drag n Down, les 3 boutons d'action ci-dessous s'exécutent automatiquement.

Pouvons-nous reprendre la discussion sur shiny-discuss ? Merci.

J'ai créé une nouvelle discussion - Réinitialiser les boutons d'action. Veuillez jeter un coup d'œil et faites-moi savoir si vous avez des entrées.

Merci.

cela a-t-il déjà été résolu ou ont-ils simplement insisté sur le fait que personne n'en avait besoin? J'en ai besoin! :)

Je me demandais s'il y avait une solution à cela aussi. J'ai besoin de la réinitialisation de actionButton car j'ai un conditionalPanel qui dépend du fait que le bouton est cliqué, mais il doit être réinitialisé chaque fois que l'utilisateur change d'option dans mon menu déroulant.

Je pense que vous pouvez utiliser ce code pour déterminer s'il est pair ou impair

x %% 2 == 0

ça marche ?

Le jeudi 8 mars 2018 à 9h06, Liquan Yang [email protected]
a écrit:

Je me demandais s'il y avait une solution à cela aussi. J'ai besoin de
actionButton reset parce que j'ai un conditionalPanel qui dépend de
si le bouton est cliqué, mais il doit être réinitialisé chaque fois que l'utilisateur
bascule les options dans mon menu déroulant.


Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-371495934 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/AK1uahF09NieR3_qn660YI8QVNfYtuz0ks5tcTrIgaJpZM4At9WK
.

En général, vous avez besoin reactiveValue lié au bouton. Chaque fois que le bouton est cliqué, il ajoute un à la reactiveValue , et cette valeur est utilisée pour déclencher des observateurs, etc. au bouton peut rester tel quel.

J'ai fini par utiliser shinyjs pour créer une checkboxInput cachée qui serait basculée par plusieurs observateurs. Ensuite, dans mon interface utilisateur, j'ai configuré un conditionalPanel pour vérifier la valeur T/F de la case à cocherInput et afficher le bouton si TRUE.

Je rencontre un problème similaire lors de l'utilisation de plusieurs observeEvents intégrés, où une réinitialisation de la valeur actionButton serait utile.

Par exemple:

     observeEvent(input$button1, { 
     #a modal with button2 pops up, but should not trigger button2 until clicked
     actionButton("button2", "Button 2")

     observeEvent(input$button2, {
      #modal number 2 pops up
      #some action
      removeModal()
      })
 })

Cette structure fonctionne parfaitement dans un premier temps. Cependant, lors du déclenchement de button1 pour la deuxième fois, il passe directement à observerEvent button2, sans que input$button2 ait été fourni.

Une enquête un peu plus approfondie avec browser() a montré que input$button2 conserve sa valeur malgré la fermeture du modal et le déclenchement de input$button1 à nouveau, SAUF si un modalButton est utilisé pour ignorer le modal au lieu de removeModal().

Une réinitialisation matérielle du bouton dans ce cas serait utile en conjonction avec removeModal (), pour empêcher l'utilisateur de l'application d'avoir à cliquer sur un modalButton de style "Dismiss" à chaque fois.

Auparavant, j'ai utilisé updateRadioButtons pour réinitialiser les entrées d'un menu de sélection, mais cela ne fonctionne pas de la même manière avec actionButtons.

Je n'ai pas trouvé de solution appropriée ci-dessus, mais j'espère vivement être corrigé par quelqu'un!

Merci beaucoup.

c'est une fonctionnalité évidemment utile - y a-t-il une raison pour laquelle ce n'est pas corrigé ???

Je rencontre un problème similaire lors de l'utilisation de plusieurs observeEvents intégrés, où une réinitialisation de la valeur actionButton serait utile.

Par exemple:

     observeEvent(input$button1, { 
     #a modal with button2 pops up, but should not trigger button2 until clicked
     actionButton("button2", "Button 2")

     observeEvent(input$button2, {
      #modal number 2 pops up
      #some action
      removeModal()
      })
 })

Cette structure fonctionne parfaitement dans un premier temps. Cependant, lors du déclenchement de button1 pour la deuxième fois, il passe directement à observerEvent button2, sans que input$button2 ait été fourni.

Une enquête un peu plus approfondie avec browser() a montré que input$button2 conserve sa valeur malgré la fermeture du modal et le déclenchement de input$button1 à nouveau, SAUF si un modalButton est utilisé pour ignorer le modal au lieu de removeModal().

Une réinitialisation matérielle du bouton dans ce cas serait utile en conjonction avec removeModal (), pour empêcher l'utilisateur de l'application d'avoir à cliquer sur un modalButton de style "Dismiss" à chaque fois.

Auparavant, j'ai utilisé updateRadioButtons pour réinitialiser les entrées d'un menu de sélection, mais cela ne fonctionne pas de la même manière avec actionButtons.

Je n'ai pas trouvé de solution appropriée ci-dessus, mais j'espère vivement être corrigé par quelqu'un!

Merci beaucoup.

J'ai le même problème qui est vraiment ennuyeux lorsque j'ai deux modaux dos à dos où le premier montre des données manquantes pour une sélection. Impossible de trouver une solution de contournement appropriée non plus

J'ai le même problème qui est vraiment ennuyeux lorsque j'ai deux modaux dos à dos où le premier montre des données manquantes pour une sélection. Impossible de trouver une solution de contournement appropriée non plus

D'accord. Pour référence future aux personnes ayant le même problème que moi. La solution la plus simple pour moi était d'inclure shinyjs::onclick() au lieu de observeEvent. Ensuite, ça marche à chaque fois. Un petit extrait de mon code :

`
observeEvent(input$change, {
showModal(modalDialog(title = "some_title",
renderTable({#mes données}),
easyClose = FAUX,
pied de page = tagList(actionButton("ok", "Ok"), shinyjs::useShinyjs())))

shinyjs::onclick("ok", {
  removeModal()

  # My other modal is in a module. Should work outside as well
  callModule(pop_up, "dato", dato_tabell = reactive({pop_up_data()}))
})

}
)
`

Désolé pour le formatage horrible. J'espère que cela aide quelqu'un

@TjebsC Pour référence future, vous pouvez contourner ce problème en donnant observeEvent(input$button2, ...) un argument supplémentaire ignoreInit=TRUE . Ce que cela indique observeEvent , c'est "quelle que soit la valeur actuelle de input$button2 , n'exécutez pas cet observateur tant que la PROCHAINE fois input$button2 n'est pas mis à jour". Pas très intuitif, mais je pense que ça devrait marcher.

Oh, ha, ce scénario exact est présenté dans ?observeEvent (bien que je ne vous reproche pas de ne pas l'avoir rencontré):

Par exemple, si vous configurez un observeEvent pour un bouton créé dynamiquement, alors ignoreInit = TRUE garantira que l'action (dans handlerExpr ) ne sera déclenchée que lorsque le bouton est en fait cliqué, au lieu d'être également déclenché lorsqu'il est créé/initialisé.

ok, je suis un même problème.

    #SAVE
    observeEvent(input$Guardar,{
    req(input$Guardar)

       input$Guardar
       isolate({

                archivo <- paste0("D:/",
                                  input$Fundo, "-", input$Parcela, " ", 
                                  input$Lote, " ", input$Lado,".pdf")

                pdf(archivo, width = 18, height = 11 )

                Graph

                dev.off()

                shinyalert(title = "Descarga Correcta", type = "success")


        })

J'ai ce code à l'intérieur d'un observeEvent pour enregistrer chaque fois que j'apporte des modifications à une carte, le problème est que dès qu'un changement de paramètre est enregistré, je veux dire lorsque je clique sur le bouton enregistrer, et cela n'arrête pas de fonctionner ; Je voudrais qu'il enregistre uniquement lorsque je clique.
J'ai besoin d'aide s'il vous plait.

Cette page vous a été utile?
0 / 5 - 0 notes