4
votes

My goal is to have a tabsetPanel wrapped in a conditionalPanel whose condition is a global variable being false.

ui.R

mainPanel(
 conditionalPanel("searchPage == \"false\"",
     tabsetPanel(
      tabPanel("Summary",htmlOutput("summary")),
      tabPanel("Description", htmlOutput("description"))
))),

global.R

searchPage <- "true"

then in server.R I assign new values to it a few different times, but all like this:

 observeEvent(input$openButton, 
           output$results <- renderUI({
             textOutput("")
             searchPage <- "false"
           }))

No matter what I do, I always get "Uncaught ReferenceError: searchPage is not defined". I've tried changing the global.R to multiple different combinations of using quotes, not using quotes, using <- or <<-, making it this.searchPage, my.searchPage and numerous other things (of course always making server.R and ui.R match too), but haven't had much luck at all.

2
This is the classical usecase for shinyjs::toggle(). Every time I need to conditionally show something where the condition is not a simple javascript expression of an input, I use shinyjs::show() or hide() or toggle()DeanAttali
I use toggle/hide/show a ton throughout my project, but I don't know that it is possible to assign a whole panel an id, so what do you call to hide the entire panel?TJ_
You can just wrap the entire panel in a div with an id. So define the panel like mainPanel(div(id = "mainpanel", ...)) and voila, there's an id to your panelDeanAttali
^ This solution ended up working a lot better than the selected answerTJ_
In that case, I added a proper "answer" so you can change the selected answer if you wantDeanAttali

2 Answers

5
votes

As mentioned in a comment on the question's post, this is a perfect usecase for the shinyjs toggle()/show()/hide() functions. Whenever you need to conditionally show something where the condition is not a simple javascript expression of an input, it's easy to use these functions instead of a conditionalPanel().

In order to use these functions, you need to have some way to specify the element you want to hide/show (in this case, the mainPanel()). The easist way to do this is to just wrap the entire panel in a div with an id. So define the panel like mainPanel(div(id = "mainpanel", ...)) and voila, there's an id to your panel, and now you can call shinyjs::show("mainpanel") or hide() whenever you want in the server code.

1
votes

What you are trying to do is not really possible the way you are trying to do it (the server and client are in different environments and don't share variables). You will need to explicitly pass the value from server to client, and there are different approaches to doing that. One way:

library(shiny)
runApp(list(ui = fluidPage(
  conditionalPanel(condition='output.bool',
                   HTML("Hello world")),
  actionButton("btn","Press me to toggle")
),
server = function(input, output, session) {
  value=TRUE
  output$bool <- eventReactive(input$btn,{
    value    
  })
  outputOptions(output,"bool",suspendWhenHidden=FALSE)

  observeEvent(input$btn,
               value <<- !value        
  )  

}))

There are probably better approaches. Hope this helps