14
votes

Can I pass a reactiveValues to a conditionalPanel's condition? If so, how?

Here is what I have tried in the conditionalPanel ui.R:

conditionalPanel(condition = "values.cond == 0", etc.

where I have defined values$cond in server.R:

values <- reactiveValues(cond = 0)

I have also tried alternatives like "values.cond == true", without success.

library("shiny")
runGist("https://gist.github.com/anonymous/8281021")

See the code:

https://gist.github.com/anonymous/8281021

3
Note that I have a workaround for the app I posted, namely using the condition condition = "input.action % 2 == 0", so my question is really restricted to this: can I pass values$cond to conditionalPanel, yes or no? Thanks!PatrickT
I think you are asking whether reactive values are exposed to the client side. With the exception of input and output objects I dont think they are.jdharrison
I see, and is there a simple way to pass reactiveValues$cond to an output$cond2 that the conditionalPanel would read? like via renderText or renderPrint or some other way? Thanks!PatrickT
You could pass it in this manner or you could look to execute a java script call using for example session$sendCustomMessagejdharrison
well thanks jd, I'll look into that (can't find an awful lot on google at this time)!PatrickT

3 Answers

11
votes

As @jdharrison pointed out, you have the problem, that you have reactive values or any other data on the server side and the conditional panel is a JS condition + some HTML on the client side. Hence, if you want to dynamically update the JS condition according to some value you calculated on the server side, you need to get the data from the server to the client. I think what you could do is use an still undocumented feature of shiny to pass custom data from the server to the client. I wrote a blog post on how to do that: http://ryouready.wordpress.com/2013/11/20/sending-data-from-client-to-server-and-back-using-shiny/

I guess you could use that approach to dynamically update the JS panel condition. You would need to write a JS function that does this after the data has been passed. So this boils down to replacing the data-display-if attribute of the conditionalPanel output with the values you want.

Another idea: If your UI strongly depends on calculations on the server side you may want to consider creating the (sidebar) content dynamically using renderUI.

EDIT: Btw, that's what @jdharrison referred to in his second comment.

6
votes

You can also do it by rendering text. UI:

shinyUI(
  fluidPage(
    # Application title
    titlePanel("Test"),

    sidebarLayout(
      sidebarPanel(
        actionButton("ShowCond", "Show Conditional Panel"),
        conditionalPanel(
          condition = "output.test=='5'",
          actionButton("CheckFile", "Check file")
        )
      ),
      mainPanel(
        verbatimTextOutput("test")
      )
    )
  )
)

Server:

shinyServer(function(input, output, session) {
  var <- eventReactive(input$ShowCond, {
    5
  })

  output$test <- renderText({
    var()
  })
})

The catch is here that it doesn't work without the verbatimTextOutput. You need to include it somewhere on your UI side. However, you could reuse it as a message.

EDIT:

It is also possible without the verbatimtext. By default Shiny suspends all output when they are not displayed. However, this can be changed by setting the following option for a specific output variable:

outputOptions(output, "test", suspendWhenHidden=FALSE)

In this case, there is nor more need to use verbatimtext (and the corresponding rendertext).

Source: https://shinydata.wordpress.com/2015/02/02/a-few-things-i-learned-about-shiny-and-reactive-programming/#use-of-isolate-to-prevent-accidental-dependencies

0
votes

Based on the above I found a work-around by using both a reactiveVal (for use else where in your app) and writing it to output like suggested above.

your_reactive <- reactiveVal(NULL)

# Read input csv file
output$your_output <- eventReactive(TRUE, {
 
  out <- ""
      
  your_reactive(out) # update server side reactive
  
  return(out)
  
  })

# Make it available on client side
outputOptions(output, "your_output", suspendWhenHidden = FALSE)

In your ui you can now access output.your_output.