Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

210
Vistas
In R Shiny, how to maintain reactivity chain when an object in the chain is hidden from view?

In the MWE code below, user inputs into the first matrix (firstInput is the name of the custom function that invokes the first matrix) are fed into a second matrix (secondInput) that the user can optionally input into, and the results of secondInput are fed into the output plot. (This link between the 2 matrices may sound absurd, but in the more complete code this is extracted from, inputs into the second matrix go through extra/intrapolations; in the spirit of MWE I removed that functionality).

In running this you can see that the user can click action button "Show" to see that 2nd matrix, since those inputs are optional.

My issue is reactivity. Currently as drafted, if the user makes a change to the value in the first matrix without showing the second matrix, then those changes are not reactively reflected in the plot. I would like data to flow through the reactivity chain even when the 2nd matrix is hidden. Is there a workaround, a simple other way, to "skin this cat"?

MWE code:

rm(list = ls())

library(shiny)
library(shinyMatrix)
library(shinyjs)

firstInput <- function(inputId){
  matrixInput(inputId, 
              value = matrix(c(5), 1, 1, dimnames = list(c("1st input"),NULL)),
              rows =  list(extend = FALSE, names = TRUE),
              cols =  list(extend = FALSE, names = FALSE, editableNames = FALSE),
              class = "numeric")}

secondInput <- function(inputId,x){
  matrixInput(inputId, 
              value = matrix(c(x), 1, 1, dimnames = list(c("2nd input"),NULL)),
              rows =  list(extend = FALSE, names = TRUE),
              cols =  list(extend = FALSE, names = FALSE, editableNames = FALSE),
              class = "numeric")}

ui <- fluidPage(
  titlePanel("Model"),
    sidebarLayout(
      sidebarPanel(
        uiOutput("panel"),
        hidden(uiOutput("secondInput")) # <<< remove "hidden" and reactivity is restored
      ),
      mainPanel(plotOutput("plot1"))
    )
  )

server <- function(input, output) {
  
  input1      <- reactive(input$input1)
  input2      <- reactive(input$input2)
  
  output$panel <- renderUI({
    tagList(
      useShinyjs(),
      firstInput("input1"),
      actionButton('show','Show 2nd inputs'),
      actionButton('hide','Hide 2nd inputs'))
  })
  
  output$secondInput <- renderUI({
    req(input1())
    secondInput("input2",input$input1[1,1])
  })
  
  output$plot1 <-renderPlot({
    req(input2())
    plot(rep(input2(),times=5))
  })
  
  observeEvent(input$show,{shinyjs::show("secondInput")})
  observeEvent(input$hide,{shinyjs::hide("secondInput")})
}

shinyApp(ui, server)
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You can do:

  output$secondInput <- renderUI({
    req(input1())
    secondInput("input2",input$input1[1,1])
  })
  outputOptions(output, "secondInput", suspendWhenHidden = FALSE)

EDIT

Another possibility is to use the CSS property visibility: hidden to hide the second input, instead of shinyjs::hidden (which sets the CSS property display: none). With this property, the second input is not visible but it takes up some space, it is not "strictly hidden".

ui <- fluidPage(
  useShinyjs(),
  tags$head(
    tags$style(HTML(".Hidden {visibility: hidden;}"))
  ),
  titlePanel("Model"),
  sidebarLayout(
    sidebarPanel(
      uiOutput("panel"),
      div(
        id = "secondInputContainer",
        class = "Hidden",
        uiOutput("secondInput")
      ) 
    ),
    mainPanel(plotOutput("plot1"))
  )
)

server <- function(input, output) {
  
  # input1      <- reactive(input$input1) useless
  # input2      <- reactive(input$input2) useless
  
  output$panel <- renderUI({
    tagList(
      firstInput("input1"),
      actionButton('show', 'Show 2nd inputs'),
      actionButton('hide', 'Hide 2nd inputs'))
  })
  
  output$secondInput <- renderUI({
    req(input$input1)
    secondInput("input2", input$input1[1,1])
  })

  output$plot1 <-renderPlot({
    req(input$input2)
    plot(rep(input$input2, times=5))
  })
  
  observeEvent(input$show, {
    removeCssClass("secondInputContainer", "Hidden")
  })
  observeEvent(input$hide, {
    addCssClass("secondInputContainer", "Hidden")
  })
}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda