Shiny: restablecer el valor de actionButton?

Creado en 7 jun. 2013  ·  71Comentarios  ·  Fuente: rstudio/shiny

¿Se puede restablecer un botón de acción a 0 dentro de server.R?
digamos que tengo actionButton("b1","button1"). ¿Cuál podría ser el código para restablecer el botón de acción a 0?

Comentario más útil

¿Se resolvió esto alguna vez o simplemente siguieron insistiendo en que nadie lo necesitaba? ¡Lo necesito! :)

Todos 71 comentarios

No, no en este momento. ¿Puedes hablar un poco sobre por qué quieres esto? Gracias...

Estaba tratando de evitar el problema con los botones de radio (y los botones de radio de actualización). Así que aquí está la lógica. Tenemos 2 botones, digamos b1 y b2. cuando se presiona un botón, se incrementa en 1 en el servidor.R representamos un texto para esta acción.después, el botón debe restablecerse a 0, de modo que si el estado de un botón es 1, debe activar alguna representación de texto, etc. pero creo que me diste la respuesta. pero sería una buena adición para mejorar el control de la interfaz de usuario. ¿Cuál es su opinión?

No piense que el valor de input$actionButtonId es significativo, _excepto_ para el caso especial de 0, que significa "el botón aún no se ha presionado". En todos los demás casos, solo debe confiar en el hecho de que input$actionButtonId cambia e invalida su expresión reactiva u observador. Si se encuentra comprobando el valor real de input$actionButtonId (aparte de la prueba de 0), entonces es una buena señal de que probablemente necesite volver a utilizar 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 realidad, creo que el reinicio es útil. Tengo una aplicación que contiene varios proyectos. Por ejemplo, cada proyecto podría ser un conjunto de datos diferente que estoy analizando, por lo que cuando cambio de proyecto me gustaría restablecer todos los botones como si nunca se hubieran presionado.

Tengo exactamente el mismo problema en el que restablecer los botones de acción ayudaría mucho. Un usuario puede cambiar ubicaciones/directorios de trabajo donde puede analizar y crear gráficos para diferentes conjuntos de datos. Para todos estos conjuntos de datos diferentes, se utilizan los mismos botones de gráfico. Tan pronto como cambie el directorio de trabajo, ahora se llamará a todos los scripts porque ya se han presionado los botones.

Estoy enfrentando este problema también. Tengo dos botones agregar y borrar para crear una consulta. cuando selecciono algo y digo agregar, ese término debe agregarse a la consulta y si hago clic en el botón borrar, debe borrar la consulta. Estoy buscando add_button>0 ahora, pero eso realmente no resolverá mi propósito porque cuando selecciono otra cosa después de hacer clic en el botón Agregar, se agregará automáticamente a la consulta. Intenté restablecer el valor del botón de acción pero realmente no pude.

En cambio, hice una solución extraña, usando una var que restablecí a 0 tan pronto como se presionó el botón. Estoy usando input$h5fileName para que el usuario pueda cargar otro archivo.

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

cuando llamo a la función que quiero ejecutar, incremento esto asegurándome de que se ejecute cada vez que presione el botón de acción.

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) {
})

Utilizo el valor de contador 1 para verificar si el archivo es correcto, usando una siguiente instrucción if con if (counter_createTime_Plot > 1) para usar el mismo botón de acción para hacer otra cosa. No es una solución bonita, pero por ahora funciona como yo quiero. Ser capaz de restablecer aún sería mucho mejor.

Todavía no creo que necesites esto. Si su lógica de adición está rodeada de aislamiento, no debería tener este problema. Si me equivoco, házmelo saber.

en el caso de sarvagna, lo más probable es que sí, ya que sospecho que su campo de entrada está en el mismo observador que ambos botones de acción (¿tal vez comparte el código?). En mi caso, sin embargo, tengo un botón que tiene que verificar la entrada de datos cuando se hace clic en él por primera vez, al hacer clic en él por segunda vez, no debe verificar la entrada de datos sino crear un gráfico en su lugar. Un tercer clic no haría nada ya que los datos están validados y se ha realizado el gráfico.

Sin embargo, el usuario también puede cambiar de archivo y, tan pronto como lo hace, el botón de trazado se vuelve inútil. En esta situación, sería perfecto si pudiera restablecer el botón de acción cuando se carga un archivo diferente. Ahora tengo que hacer un seguimiento de cuántas veces se hace clic con una variable de contador externa.

Aquí está mi código, traté de usar la lógica que mencionaste. esto funciona bien la primera vez que hago clic en el botón Agregar o Borrar. pero después de eso los botones son inútiles.

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

Intente usar dos observadores, uno para cada botón. Además, ¿qué son DisplayString y QueryString? ¿Solo listas normales u objetos reactiveValues?

son objetos de valores reactivos. Usaré la cadena de visualización en la salida de texto literal y la cadena de consulta en la función de consulta de db más abajo en el código

En ese caso, la salida $ valor_dinámico solo debe asignarse una vez, fuera de cualquier observador.

Bueno, hice algo como esto y parece estar funcionando por ahora.

#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=",")
  })

Realmente desearía poder restablecer un botón de acción a 0.

@sharko666 Avísame si tienes un ejemplo simple de por qué lo necesitas. Estoy totalmente abierto a que me convenzan, pero hasta ahora no he visto ningún escenario que no se haya manejado mejor usando los modismos que ya hemos establecido.

Joe, ¿me enviaste esto por error? No soy sharko666.

El lunes 13 de octubre de 2014 a las 11:29 a. m., Joe Cheng [email protected]
escribió:

@sharko666 https://github.com/sharko666 Avísame si tienes un
ejemplo simple de por qué lo necesitas. Estoy totalmente abierto a que me convenzan
pero no he visto ningún escenario hasta ahora que no se haya manejado mejor usando el
modismos que ya hemos establecido.


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-58934438 .

Marc david Cohen | Director científico | +1.415.205.6295 |
www.aktana.com

_El poder de muchos, el foco de uno_

@Marccohen Probablemente recibió una copia del mensaje porque está viendo el repositorio brillante en github.

Hola Joe,
Estoy trabajando en una aplicación que toma una URL en un campo de texto y carga conjuntos de datos desde una URL. Eso funciona bien siempre que el usuario copie y pegue la URL en el campo de texto. Si hay un error en la URL o está ingresada, shiny intenta constantemente cargar datos de una URL incompleta. Es por eso que pensé en agregarle un botón de envío. Eso mejoró las cosas que ahora la URL también se puede escribir ya que no pasa nada mientras se presiona el botón. El nuevo problema surge cuando se escribe otra URL después de la primera. El contador ya es mayor que 0, por lo que el botón se marca como presionado. Entonces esto funciona solo por primera vez. Este problema se habría resuelto fácilmente si hubiera una forma de restablecer el contador en la parte lógica cuando se carga el conjunto de datos o se detecta un error apropiado (si la URL sigue siendo incorrecta).

Ahora, encontré una solución, pero podría no ser la solución, ya que se supone que funciona el brillo. Tengo una variable global establecida en la función reactiveValues ​​llamada actionCounter. Cada vez que se presiona el botón, el contador de botones aumenta y es más alto que el contador de acciones. Dentro de la lógica, el contador de acciones se establece en el contador de botones. Ahora solo pruebo si el actionCounter es más bajo que el buttonCounter. Vea el código a continuación.

servidor.R

vars = valores reactivos (contador de acciones = 0)

dentro del observador para el campo de texto

url = entrada$URL_entrada
if(!is.null(input$submit_URL)){
if(input$submit_URL>vars$actionCounter&url!=""){
vars$actionCounter=input$submit_URL
# intenta cargar los datos
}
}

Entonces, hay una solución relativamente fácil, pero si existiera la posibilidad de restablecer el contador del botón, habría sido más simple y más fácil de entender.

Saludos

Cristóbal


De: Marc Cohen [[email protected]]
Enviado: martes, 14 de octubre de 2014 7:37
Para: rstudio/brillante
CC: Christoph Knapp
Asunto: Re: [brillante] ¿valor de reinicio de actionButton? (#167)

Joe, ¿me enviaste esto por error? No soy sharko666.

El lunes 13 de octubre de 2014 a las 11:29 a. m., Joe Cheng [email protected]
escribió:

@sharko666 https://github.com/sharko666 Avísame si tienes un
ejemplo simple de por qué lo necesitas. Estoy totalmente abierto a que me convenzan
pero no he visto ningún escenario hasta ahora que no se haya manejado mejor usando el
modismos que ya hemos establecido.


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-58934438 .

Marc david Cohen | Director científico | +1.415.205.6295 |
www.aktana.com

_El poder de muchos, el foco de uno_


Responda a este correo electrónico directamente o véalo en Gi tHubhttps://github.com/rstudio/shiny/issues/167#issuecomment -58935448.

Gracias por la respuesta. Esta es la forma idiomática de manejar tal situación:

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

Luego, en cualquier lugar donde desee acceder a la URL, use url() .

Es una queja de larga data contra Shiny que no tenemos funciones de envoltura para este idioma.

@sharko666 Acabo de fusionar una solicitud de extracción muy antigua en la maestra. Con este cambio, ahora puede hacer esto en su lugar:

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

Básicamente, esto significa que "el valor de url no es nada (NULO) al principio, pero cada vez que se hace clic input$submit_URL , configúrelo en el valor actual de input$URL_input ".

También hay una función complementaria observeEvent :

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

La parte "hacer algo" del código se ejecutará cuando y solo cuando se haga clic en el botón.

@jcheng5 Acabo de usar la nueva versión de Shiny - 10.2.9 para la nueva función de observeEvent. Funciona muy bien en mi versión de escritorio de R Studio, pero estoy tratando de ejecutarlo usando una instalación portátil de R y Chrome desde una unidad flash. Esto funcionó bien con shiny 10.2.1 porque pude encontrar un zip que funcionó para shiny 10.2.1. He intentado ir a través de github, pero no estoy seguro de cómo puedo encontrar (o crear) un zip 10.2.9 que funcione para una instalación portátil (32 bits) de R. Si pudiera señalar en la dirección correcta, sería muy apreciado. Gracias :)

@dakshvarma ¿Hay alguna razón por la que devtools::install_github` no funcione con su R portátil?

@ jcheng5 ¡Por fin funcionó! devtools::install_github lo instala creando una carpeta local. El truco es comprimir la carpeta local, instalar un paquete desde el zip en la instalación portátil (con el zip en la misma carpeta que la R portátil). ¡Gracias por tu ayuda!

tengo el siguiente caso:
2 botones de acción (Generar y Restablecer) que deben usarse en UN renderPlot.
¿Cómo manejar esta situación? Aprecio tu ayuda

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

¿Qué hace Restablecer, borrarlo? ¿Cuál debería ser el estado inicial de la trama?
ser: ¿debería generarse cuando la aplicación se inicia por primera vez, o debería ser
¿vacío?

El martes 18 de noviembre de 2014 a las 8:37 a. m., Hratch [email protected] escribió:

tengo el siguiente caso:
2 botones de acción (Generar y Restablecer) que deben usarse bajo UNO
renderPlot.
¿Cómo manejar esta situación? Aprecio tu ayuda

salida$Resultado <- renderPlot({
si (entrada $ GEN_button == 0){
#milogica
}
más si si (entrada $ RES_button == 0) {
#milogica
}
demás {
#milogica
}
})


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63500459 .

Restablecer restablece el valor de la matriz que se trazará a un valor inicial.
El estado inicial (ejecución inicial) debe mostrar la matriz que se crea dentro de la lógica.
Si se hace clic en el botón Generar, se generará y trazará una nueva matriz.

Eso significa que la matriz también se puede calcular fuera de renderPlot, ¿verdad?

En ese caso, parece que tanto Generar al reiniciar no debería afectar el
trazar directamente, sino un valor de matriz.

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

Gracias por su rápida retroalimentación/solución, eres genial.

Estoy tratando de hacer algo similar y tengo varios problemas:

  1. Acepto una frase, proceso la frase y predigo una palabra, vuelvo a agregar la palabra predicha en la entrada. Pero esto provoca un bucle infinito. ¿Hay alguna manera de arreglar esto?
  2. Luego creé un cuadro de texto para la palabra predicha y luego agregué un botón "Aceptar". Si el usuario presiona Aceptar, la palabra se agrega a la frase existente. Sin embargo, no puedo hacer que esto funcione. El código está abajo:

ui.R:
textInput("palabra", "Frase", valor=""),
textInput("palabra predicha", "Palabra siguiente:", valor=""),
botonaccion("aceptar", "Aceptar")

servidor.R
servidorbrillante(
función (entrada, salida, sesión) {
observar ({
si (entrada$aceptar > 0) {
predicho <- pegar(entrada$palabra, entrada$palabrapredicha)
updateTextInput(sesión, "palabra", valor = predicho)
}
demás {
regreso()
}
})

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

})

El ciclo infinito se puede arreglar agregando la función en negrita:

si (entrada$aceptar > 0) {

  • aislar({*
    predicho <- pegar(entrada$palabra, entrada$siguientepalabra)
    updateTextInput(sesión, "palabra", valor = predicho)
  • })*
    }

Este es casi siempre el patrón que desea seguir al usar
botón de acción. De hecho, tenemos algunas funciones en Shiny que
envuelve este patrón para que sea más natural seguirlo.

Consulte http://shiny.rstudio.com/articles/isolation.html para obtener más detalles.

El jueves 20 de noviembre de 2014 a las 11:27 a. m., Shanthi [email protected] escribió:

Estoy tratando de hacer algo similar y tengo varios problemas:

  1. Acepto una frase, proceso la frase y predigo una palabra, agrego la
    palabra predicha de nuevo en la entrada. Pero esto provoca un bucle infinito. Es
    hay una manera de arreglar esto?
  2. Luego creé un cuadro de texto para la palabra predicha y luego agregué un botón
    "Aceptar". Si el usuario presiona Aceptar, la palabra se agrega a la existente
    frase. Sin embargo, no puedo hacer que esto funcione.

ui.R:
textInput("palabra", "Frase", valor=""),
textInput("palabra predicha", "Palabra siguiente:", valor=""),
botonaccion("aceptar", "Aceptar")

servidor.R
servidorbrillante(
función (entrada, salida, sesión) {
observar ({
si (entrada$aceptar > 0) {
predicho <- pegar(entrada$palabra, entrada$siguientepalabra)
updateTextInput(sesión, "palabra", valor = predicho)
}
demás {
regreso()
}
})

observar({
palabra siguiente <- toString(predict(input$word,all.gram,4))
updateTextInput(sesión, "palabra predicha", valor = siguiente palabra)
})

})


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63864397 .

Genial, eso funcionó muy bien. Gracias por su rápida respuesta.

¿Es posible colocar el cursor al final del texto en el escenario anterior? Básicamente, cuando el usuario hace clic en "Aceptar", agrego el texto al texto de entrada pero quiero colocar el cursor al final.

Esto tiene que hacerse con JS. Intente incluir esto en su interfaz de usuario.

etiquetas$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var entrada = $('#palabra');
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
"))

Inmediatamente después de llamar a updateTextInput(session, "word", ...), debe agregar:
session$sendCustomMessage("cursorEnd", NULL)

El jueves 20 de noviembre de 2014 a las 12:55 p. m., Shanthi [email protected] escribió:

¿Es posible poner el cursor al final del texto en el anterior?
¿guión? Básicamente, cuando el usuario hace clic en "Aceptar", agrego el texto a la
texto de entrada pero quiero colocar el cursor al final.


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63878009 .

Joe - esto no hace nada. Mi ui.R y server.R están a continuación:
biblioteca (brillante)
biblioteca (stringi)
biblioteca (tabla de datos)

interfaz de usuario brillante (página fluida (
titlePanel("TextPredictor"),
filafluida(
columna(6, pozoPanel(
textInput("palabra", "Frase", valor=""),
etiquetas$estilo(tipo='texto/css', "#palabra { ancho: 300px; }"),
etiquetas$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var entrada = $('#palabra');
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
")) ,
botón de acción ("borrar", "Borrar"),
textInput("palabra predicha", "Palabra siguiente:", valor=""),
botonaccion("aceptar", "Aceptar")
))
)))

servidor.R
servidorbrillante(
función (entrada, salida, sesión) {
observar ({
si (entrada$aceptar > 0) {
aislar({
frase <- limpiar(entrada$palabra)
predicho <- pegar (frase, entrada $ palabra predicha)
updateTextInput(sesión, "palabra", valor = predicho)
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)
})  

})

Lo siento, dos errores:

Shiny.addCustomMessageHandler('cursorEnd', function() {
debiera ser
Shiny.addCustomMessageHandler('cursorEnd', function(_message_) {

y

session$sendCustomMessage("cursorEnd", NULL)
debiera ser
session$sendCustomMessage("cursorEnd", TRUE)

El jueves 20 de noviembre de 2014 a las 2:50 p. m., Shanthi [email protected] escribió:

Joe - esto no hace nada. Mi ui.R y server.R están a continuación:
biblioteca (brillante)
biblioteca (stringi)
biblioteca (tabla de datos)

interfaz de usuario brillante (página fluida (
titlePanel("TextPredictor"),
filafluida(
columna(6, pozoPanel(

textInput("palabra", "Frase", valor=""),
etiquetas$estilo(tipo='texto/css', "#palabra { ancho: 300px; }"),
etiquetas$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var entrada = $('#palabra');
alerta (entrada)
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
")) ,
botón de acción ("borrar", "Borrar"),
textInput("palabra predicha", "Palabra siguiente:", valor=""),
botonaccion("aceptar", "Aceptar")
))
)))

servidor.R
servidorbrillante(
función (entrada, salida, sesión) {
observar ({
si (entrada$aceptar > 0) {
aislar({
frase <- limpiar(entrada$palabra)
predicho <- pegar (frase, entrada $ palabra predicha)
updateTextInput(sesión, "palabra", valor = predicho)
session$sendCustomMessage("cursorEnd", NULL)
})
}
})

observar ({
si (entrada $ claro > 0) {
aislar({
actualizarTextInput(sesión, "palabra", valor = "")
})
}
})

observar({
frase <- limpiar(entrada$palabra)
palabra siguiente <- toString(predict(frase,all.gram,4))
updateTextInput(sesión, "palabra predicha", valor = siguiente palabra)
})

})


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63894797 .

Muy buena solución, gracias una vez más. Ni siquiera sabía que estos métodos existen en Shiny.

Tengo un nuevo problema. Puedo agregar el texto y configurar el cursor, sin embargo, el cursor no está visible. Siempre veo la primera parte del texto y el texto no se desplaza hacia la derecha.

Convertí texto en área de texto y veo el mismo problema. ¿Cómo puedo enfocar el final del área de texto? Gracias

Siento que se ha pasado por alto un caso simple (y perdóname si de alguna manera me perdí este ejemplo en el hilo anterior). Es muy común tener un conjunto de casillas de verificación con un botón para marcar todo y otro para desmarcar todo. Por ejemplo, el código deseado de server.R a continuación. Si bien puedo concebir algunas formas de evitar esto, no significa que no deba poder restablecer a 0. La razón por la cual el código a continuación no funciona es que después de seleccionar y anular la selección una vez, ambos valores de botón de acción de entrada son mayores que 0. No obtengo nada significativo del contador de incrementos que no sea "el valor especial de 0" como se indicó anteriormente. ¿Pensamientos sobre este ejemplo?

observar({
si (entrada $ desmarcar todo > 0) {
updateCheckboxGroupInput(sesión = sesión, inputId = "prueba", opciones = c(1,2,3), seleccionado = NULL)
}
if (entrada$marcarTodos > 0) {
actualizarCheckboxGroupInput(sesión = sesión, inputId = "prueba", opciones = c(1,2,3), seleccionado = c(1,2,3))
}
})

Estos solo necesitan ser dos observadores separados.

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 realidad, con las versiones recientes de Shiny, es mejor usar observeEvent, y tampoco es necesario que proporcione las opciones si no cambian:

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

Muchas gracias, esto realmente tiene sentido y estoy corregido. Todavía no entiendo muy bien la resistencia a no poder restablecer a cero; no parece promover inherentemente ninguna mala práctica de codificación, y el hecho de que algo se pueda hacer de una manera no significa que no pueda haber una mejor. o forma más intuitiva. De todos modos, ha encontrado soluciones elegantes para la mayoría de los problemas aquí, así que por ahora esto definitivamente será suficiente. Además, gracias por el consejo sobre observeEvent(). Ni siquiera estaba al tanto de esta nueva construcción (soy relativamente nuevo en shiny, y algunos de los ejemplos en la galería parecen usar algunas de las funciones más nuevas que estoy encontrando).

Todavía no entiendo muy bien la resistencia a no poder restablecer a cero; no parece promover inherentemente ninguna mala práctica de codificación.

Absoluta y positivamente promueve malas prácticas de codificación. Solo mire todos los ejemplos de código en este hilo (sin culpa de los usuarios, por supuesto, simplemente no hemos hecho un trabajo lo suficientemente bueno con la educación). El botón de acción en el que se hace clic debe considerarse un evento discreto, no un valor. El valor especial 0 es solo una solución para evitar que el código piense que se hizo clic en el botón al inicio. Es _el hecho de que un número ha cambiado_ lo que es la señal relevante aquí, no _el valor que tiene el número_.

El sistema de reactividad de Shiny no fue diseñado para programación imperativa, y presionar un botón es, por naturaleza, imperativo. Fue un golpe de pura suerte que se me ocurriera la expresión observar/aislar que permite que los botones de acción funcionen tan bien. Es un patrón muy estrecho que tiene aplicaciones muy amplias; si te mantienes dentro del patrón, puedes lograr casi cualquier cosa de manera segura. Si se desvía del patrón, de repente es muy difícil razonar sobre su programa Y probablemente tampoco logre lo que originalmente quería que hiciera.

Creo que parte de la razón es que los ejemplos de observar/aislar no se parecen a nada particularmente especial en relación con otro código reactivo. Espero que observeEvent ayude a aclarar la intención y que sea menos tentador abusar.

Todavía no estoy de acuerdo con esta premisa. Hay una diferencia entre promover malas prácticas de codificación y personas que usan el código de manera incorrecta. Casi cualquier construcción de código se puede usar de manera inapropiada. Creo que la raíz de este desacuerdo puede ser la implementación del contador para el botón de acción, que podría argumentar que no es intuitivo basado en muchos ejemplos anteriores que encontré usando observe. Concederé fácilmente que la interfaz para observeEvent es mucho más limpia y, naturalmente, ofuscará el valor asociado con el botón de acción. En cualquier caso, muchas gracias por su ayuda. Si desea continuar la conversación sobre la promoción de malas prácticas de codificación, no dude en enviarme un correo electrónico, ya que no quiero que este hilo se desvíe demasiado del tema. Por supuesto, si se relaciona con los ejemplos y casos de uso, definitivamente publique aquí. Gracias de nuevo.

nota lateral rápida. En mi ejemplo uncheckAll, usé selected = NULL dentro de updateCheckboxGroupInput. Según la documentación de este método, se ignorarán todos los argumentos con un valor NULL. Por lo tanto, para aquellos que miran este ejemplo, deben usar selected = c('') o algún equivalente.

Hola, creo que actualmente hay un problema con el enfoque: si elimina y agrega el botón con la misma ID nuevamente, el input$ID aún podría existir y, por lo tanto, ya no es nulo, por lo tanto, la función se ejecuta inmediatamente cuando agregado, solucioné ese problema extendiendo la función observeEvent de la siguiente manera (en pocas palabras: primero obtengo el valor anterior y luego lo comparo con el nuevo evento):

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

Todavía no es perfecto, pero funciona mucho mejor.

Yo también me encuentro queriendo restablecer un botón de acción. No encuentro la siguiente funcionalidad en el hilo hasta ahora, así que lo probaré para Joe...

Tiene que ver con el uso de un panel condicional que busca el valor de un botón de acción para su condición (esto está en ui.R, _not_ server.R).

En un panel lateral tengo algo como:

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

luego en un panel principal tengo algo como

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

Ahora, en algún momento (tal vez provocado por otro botón de acción, me gustaría restablecer input.doit y volver a mostrar el primer panel condicional, hacer que el usuario vuelva a especificar las entradas allí, etc. Parece que sería bastante natural tener algo así como updateActionButton() en server.R para volver a mi primer panel condicional.

Me encantaría escuchar la forma 'correcta y adecuada' de hacer esto, dado que updateActionButton() no existe.

Para obtener un botón de acción 0/1 sin reiniciar:

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

Me topé con este problema mientras buscaba una forma de escribir un controlador único que pudiera responder a una gran cantidad de botones de acción individuales (que cambian dinámicamente). Aquí hay un ejemplo de lo que estaba tratando de hacer:

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

Podría ver que el 'restablecer' a cero es útil en este caso, pero tal vez haya una mejor manera de hacerlo.
¿Alguien ha hecho algo similar?

@mikebirdgeneau Eso no es absolutamente necesario en este caso. Esto es todo lo que necesitas hacer:

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 gracias - ¡Lo intentaré! Agradezco la rápida respuesta. Salud.

Puedo ver un argumento para restablecer un botón de acción que no he visto mencionado aquí (disculpas si se ha mencionado y me lo perdí). Me gustaría poder copiar la URL del navegador en el que se ejecuta mi aplicación brillante, enviársela a otra persona y que pueda cargar la misma página con todas las entradas rellenadas automáticamente desde la URL. Sin embargo, no quiero que las acciones ejecutadas por un actionButton se ejecuten automáticamente. (Un ejemplo de esto podría ser una página utilizada para visualizar datos, con un botón de acción que activará la escritura de esos datos en un archivo en particular. Quiero poder enviar una visualización de esos datos a alguien enviándole la URL a mi página, pero es posible que no quieran escribirlo en el archivo al cargar la página).

Por defecto, shiny puede guardar/cargar todas sus variables de entrada a/desde la URL, lo cual es excelente la mayor parte del tiempo, pero puede causar problemas cuando carga botones de acción con valores > 0. En esos casos, como en el ejemplo anterior, pensará que el usuario ha hecho clic en el botón de acción cuando en realidad aún no lo ha hecho.

Este es un caso en el que el valor del actionButton no importa, pero el hecho de que no sea cero es importante. ¡Gracias por tu ayuda!

Por defecto, shiny puede guardar/cargar todas sus variables de entrada a/desde la URL

Esa no es una función integrada de Shiny; ¿Hay algún paquete específico que esté utilizando para brindarle esa funcionalidad?

Tiene razón: esto es parte de un paquete separado (que aún no está disponible públicamente). Gracias por la rápida respuesta.

¿ @nhpackard le ayuda shinyjs a lograr lo que necesita? Aquí hay un ejemplo mínimo 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")
    }) 

  }
)

No está usando conditionalPanel pero creo que es más limpio mantener la lógica del lado del servidor. Al presionar un botón, puede tener updateX para cada una de las entradas y ejecutar el análisis, etc.

Hola Joe,

Me quedé con el problema similar relacionado con el reinicio del botón de acción. Mi problema es

En la interfaz de usuario: tengo 1 arrastre hacia abajo que contiene 2 valores "Suntrust Bank" y "Huntington Bank". Y debajo de los cuales tengo 3 botones de acción para 3 tareas: procesar datos, descargar datos procesados ​​y cargar datos procesados.

Cuando selecciono Suntrust por primera vez, los siguientes tres botones de acción no se ejecutan a menos que los presione. Sin embargo, cada vez que selecciono Huntington, debajo de 3 botones se ejecutan automáticamente (no se presionaron los botones).

¿Podría por favor ayudarme a resolver esto? Idealmente, me gustaría tener: cuando cambie SunTrust a Huntington o y nuevamente Huntington a SunTrust, los 3 botones a continuación (procesar, descargar y cargar) no deberían funcionar a menos que los presione.

Gracias por adelantado !!

Me gusta esto:

observarEvento(entrada$proceso, {
# código de procesamiento aquí
})
observarEvento(entrada$descarga, {
# código de descarga aquí
})
observarEvento(entrada$subir, {
# cargar código aquí
})

El martes 26 de enero de 2016 a las 10:18 abhijeetgosavi [email protected]
escribió:

Hola Joe,

Me quedé con el problema similar relacionado con el restablecimiento de la acción.
botón. Mi problema es

En la interfaz de usuario: tengo 1 arrastre hacia abajo que contiene 2 valores "Suntrust Bank" y
"Banco de Huntington". Y debajo de los cuales tengo 3 botones de acción para 3 tareas:
procesar datos, descargar datos procesados ​​y cargar datos procesados.

Cuando selecciono Suntrust por primera vez, debajo de tres botones de acción no están
ejecutado a menos que los presioné. Sin embargo, cada vez que selecciono Huntington,
debajo de 3 botones ejecutados automáticamente (los botones no fueron presionados) .

¿Podría por favor ayudarme a resolver esto? Idealmente me gustaría
tengo: cuando cambio SunTrust a Huntington o y de nuevo Huntington a
SunTrust, los 3 botones a continuación (procesar, descargar y cargar) no deben
trabajo a menos y hasta que los presione.

Gracias por adelantado !!


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-175154688 .

Sí exactamente. Déjame pegar mi código server.r aquí
Servidor.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

interfaz de usuario brillante (página fluida (
titlePanel("Generar archivo GI de tarifa de la competencia"),

diseño de la barra lateral (

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")
         )
         )

))

Cuando cambio de banco de Suntrust a Huntington desde Drag n Down, los siguientes 3 botones de acción se ejecutan automáticamente.

¿Podemos llevar la discusión a shiny-discuss ? Gracias.

He creado una nueva discusión: restablecer los botones de acción. Por favor, eche un vistazo y avíseme si tiene alguna entrada.

Gracias.

¿Se resolvió esto alguna vez o simplemente siguieron insistiendo en que nadie lo necesitaba? ¡Lo necesito! :)

Me preguntaba si había una solución a esto también. Necesito restablecer el botón de acción porque tengo un panel condicional que depende de si se hace clic en el botón, pero debe restablecerse cada vez que el usuario cambia de opción en mi menú desplegable.

Creo que puedes usar este código para determinar si es par o impar

x %% 2 == 0

¿Eso funciona?

El jueves 8 de marzo de 2018 a las 9:06 a. m., Liquan Yang [email protected]
escribió:

Me preguntaba si había una solución a esto también. Necesito el
reinicio del botón de acción porque tengo un panel condicional que depende de
si se hace clic en el botón, pero debe restablecerse cada vez que el usuario
cambia las opciones en mi menú desplegable.


Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-371495934 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AK1uahF09NieR3_qn660YI8QVNfYtuz0ks5tcTrIgaJpZM4At9WK
.

En general, lo que necesita es reactiveValue que está vinculado al botón. Cada vez que se hace clic en el botón, se agrega uno al valor, y ese valor se usa para activar observadores, etc. Luego, cuando el usuario hace lo que restablece las cosas, simplemente restablece reactiveValue a 0, el valor empatado al botón puede permanecer como está.

Terminé usando shinyjs para crear una entrada de casilla de verificación oculta que varios observadores alternarían. Luego, en mi interfaz de usuario, configuré un panel condicional para verificar el valor T/F de la entrada de casilla de verificación y mostrar el botón si es VERDADERO.

Estoy experimentando un problema similar cuando uso múltiples eventos de observación incrustados, donde sería útil restablecer el valor del botón de acción.

Por ejemplo:

     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()
      })
 })

Esta estructura funciona perfectamente en primera instancia. Sin embargo, cuando se activa el botón 1 por segunda vez, salta directamente a observar el botón 2 de evento, sin que se haya proporcionado input$button2.

Un poco más de investigación con browser() mostró que input$button2 retiene su valor a pesar de cerrar el modal y activar input$button1 nuevamente, A MENOS que se use un modalButton para descartar el modal en lugar de removeModal().

Un restablecimiento completo del botón en este caso sería útil junto con removeModal(), para evitar que el usuario de la aplicación tenga que hacer clic en un modalButton de estilo "Descartar" cada vez.

Anteriormente, he usado updateRadioButtons para restablecer las entradas de un menú de selección, pero esto no funciona igual con los botones de acción.

No he encontrado una solución adecuada arriba, ¡pero espero que alguien me corrija!

Muchas gracias.

esa es una característica obviamente útil. ¿Hay algún razonamiento por el que esto no se solucione?

Estoy experimentando un problema similar cuando uso múltiples eventos de observación incrustados, donde sería útil restablecer el valor del botón de acción.

Por ejemplo:

     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()
      })
 })

Esta estructura funciona perfectamente en primera instancia. Sin embargo, cuando se activa el botón 1 por segunda vez, salta directamente a observar el botón 2 de evento, sin que se haya proporcionado input$button2.

Un poco más de investigación con browser() mostró que input$button2 retiene su valor a pesar de cerrar el modal y activar input$button1 nuevamente, A MENOS que se use un modalButton para descartar el modal en lugar de removeModal().

Un restablecimiento completo del botón en este caso sería útil junto con removeModal(), para evitar que el usuario de la aplicación tenga que hacer clic en un modalButton de estilo "Descartar" cada vez.

Anteriormente, he usado updateRadioButtons para restablecer las entradas de un menú de selección, pero esto no funciona igual con los botones de acción.

No he encontrado una solución adecuada arriba, ¡pero espero que alguien me corrija!

Muchas gracias.

Tengo el mismo problema que es realmente molesto cuando tengo dos modales consecutivos donde el primero muestra datos faltantes para una selección. Tampoco se pudo encontrar una solución adecuada

Tengo el mismo problema que es realmente molesto cuando tengo dos modales consecutivos donde el primero muestra datos faltantes para una selección. Tampoco se pudo encontrar una solución adecuada

Está bien. Para referencia futura a personas que tienen el mismo problema que yo. La solución fácil para mí fue incluir shinyjs::onclick() en lugar de observeEvent. Entonces funciona cada vez. Un breve fragmento de mi código:

`
observarEvento(entrada$cambio, {
showModal(modalDialog(titulo = "algun_titulo",
renderTable({#mis datos}),
cierrefácil = FALSO,
pie de página = 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()}))
})

}
)
`

Lo siento por el formato terrible. Espero que esto ayude a alguien

@TjebsC Para referencia futura, puede solucionar esto dando observeEvent(input$button2, ...) un argumento adicional ignoreInit=TRUE . Lo que esto le dice a observeEvent es, "no importa cuál sea el valor actual de input$button2 , no ejecute este observador hasta la PRÓXIMA vez que se actualice input$button2 ". No es muy intuitivo, pero creo que debería funcionar.

Oh, ja, este escenario exacto se presenta en ?observeEvent (aunque no te culpo por no encontrarlo):

Por ejemplo, si está configurando observeEvent para un botón creado dinámicamente, entonces ignoreInit = TRUE garantizará que la acción (en handlerExpr ) solo se activará cuando el botón se hace clic en realidad, en lugar de activarse también cuando se crea/inicializa.

ok yo tengo el mismo problema

    #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")


        })

Tengo este código dentro de un observeEvent para guardar cada vez que hago cambios en un mapa, el problema es que en cuanto se guarda un cambio de parámetro, es decir cuando hago clic en el botón guardar, y no deja de funcionar; Me gustaría que solo se guarde cuando hago clic.
Necesito ayuda por favor.

¿Fue útil esta página
0 / 5 - 0 calificaciones