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)
CodePudding user response:
You can do:
output$secondInput <- renderUI({
req(input1())
secondInput("input2",input$input1[1,1])
})
outputOptions(output, "secondInput", suspendWhenHidden = FALSE)