Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

201
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!