How to hide a conditional panel in Shiny? Please, see the following example:
library(shiny)
ui <- fluidPage(
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
conditionalPanel(
condition = "input.eval",
"text"))
server <- function(input, output, session) {
observeEvent(input$num_input, {
input$eval <- 0
})}
shinyApp(ui, server)
What I want to achieve is: Once the user clicks the evaluate-button the conditional panel should appear, but once the number in num_input is changed the panel should disappear. My idea was to null the evaluate-button, but this does not work (the app opens with gray background and seems frozen).
I also tried it with shinyjs like so:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
conditionalPanel(
id = "cond_panel",
condition = "input.eval",
"text"))
server <- function(input, output, session) {
observeEvent(input$num_input, {
reset("cond_panel")})}
shinyApp(ui, server)
But this does not work either: the app opens regularly and the conditional panel is shown once the evaluate-button is clicked, but nothing happens once the number is changed.
You can create an output value and use it just for the conditional panel. The article on dynamic UI explains how to do this:
http://shiny.rstudio.com/articles/dynamic-ui.html
The condition can also use output values; they work in the same way (output.foo gives you the value of the output foo). If you have a situation where you wish you could use an R expression as your condition argument, you can create a reactive expression in the server function and assign it to a new output, then refer to that output in your condition expression.
If you do this, make sure to also set outputOptions(output, [newOutputName], suspendWhenHidden = FALSE). (This is necessary because Shiny normally doesn’t send values to the browser for outputs that are hidden or not present in the UI. In this case, however, the browser does need to know the most up-to-date output value in order to correctly evaluate the condition of the contitionalPanel function - suspendWhenHidden = FALSE ensures this will happen.)
library(shiny)
ui <- fluidPage(
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
conditionalPanel("input.eval && !output.hide_panel", "text")
)
server <- function(input, output, session) {
output$hide_panel <- eventReactive(input$num_input, TRUE, ignoreInit = TRUE)
outputOptions(output, "hide_panel", suspendWhenHidden = FALSE)
}
shinyApp(ui, server)
Another way would be to renderUI the conditional panel, and show it until input$num_input changes.
I have never played much with conditionalPanel, so not sure if it has default settings to hide/show. Following might work to give you the desired output.
library(shiny)
library(shinyjs)
if(interactive()){
shinyApp(
ui <- fluidPage(
shinyjs::useShinyjs(),
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
shinyjs::hidden(
div(
id = "cp1",
conditionalPanel(condition = "input.eval",
textOutput("text1")))
)
),
server = function(input, output, session){
output$text1 <- renderText({
input$num_input
})
observeEvent(input$eval,{
shinyjs::show("cp1")
})
observeEvent(input$num_input,{
shinyjs::hide("cp1")
})
}
)
}
I am hiding the conditionalPanel initially using shinyjs, displaying numeric input entered using renderText, and having two observeEvent to hide\show the panel accordingly.
Related
How to hide a conditional panel in Shiny? Please, see the following example:
library(shiny)
ui <- fluidPage(
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
conditionalPanel(
condition = "input.eval",
"text"))
server <- function(input, output, session) {
observeEvent(input$num_input, {
input$eval <- 0
})}
shinyApp(ui, server)
What I want to achieve is: Once the user clicks the evaluate-button the conditional panel should appear, but once the number in num_input is changed the panel should disappear. My idea was to null the evaluate-button, but this does not work (the app opens with gray background and seems frozen).
I also tried it with shinyjs like so:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
conditionalPanel(
id = "cond_panel",
condition = "input.eval",
"text"))
server <- function(input, output, session) {
observeEvent(input$num_input, {
reset("cond_panel")})}
shinyApp(ui, server)
But this does not work either: the app opens regularly and the conditional panel is shown once the evaluate-button is clicked, but nothing happens once the number is changed.
You can create an output value and use it just for the conditional panel. The article on dynamic UI explains how to do this:
http://shiny.rstudio.com/articles/dynamic-ui.html
The condition can also use output values; they work in the same way (output.foo gives you the value of the output foo). If you have a situation where you wish you could use an R expression as your condition argument, you can create a reactive expression in the server function and assign it to a new output, then refer to that output in your condition expression.
If you do this, make sure to also set outputOptions(output, [newOutputName], suspendWhenHidden = FALSE). (This is necessary because Shiny normally doesn’t send values to the browser for outputs that are hidden or not present in the UI. In this case, however, the browser does need to know the most up-to-date output value in order to correctly evaluate the condition of the contitionalPanel function - suspendWhenHidden = FALSE ensures this will happen.)
library(shiny)
ui <- fluidPage(
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
conditionalPanel("input.eval && !output.hide_panel", "text")
)
server <- function(input, output, session) {
output$hide_panel <- eventReactive(input$num_input, TRUE, ignoreInit = TRUE)
outputOptions(output, "hide_panel", suspendWhenHidden = FALSE)
}
shinyApp(ui, server)
Another way would be to renderUI the conditional panel, and show it until input$num_input changes.
I have never played much with conditionalPanel, so not sure if it has default settings to hide/show. Following might work to give you the desired output.
library(shiny)
library(shinyjs)
if(interactive()){
shinyApp(
ui <- fluidPage(
shinyjs::useShinyjs(),
actionButton("eval","Evaluate"),
numericInput("num_input", "If number is changed, cp must hide", value = 0),
shinyjs::hidden(
div(
id = "cp1",
conditionalPanel(condition = "input.eval",
textOutput("text1")))
)
),
server = function(input, output, session){
output$text1 <- renderText({
input$num_input
})
observeEvent(input$eval,{
shinyjs::show("cp1")
})
observeEvent(input$num_input,{
shinyjs::hide("cp1")
})
}
)
}
I am hiding the conditionalPanel initially using shinyjs, displaying numeric input entered using renderText, and having two observeEvent to hide\show the panel accordingly.
I am trying to create a shiny app where it allows you to select an input of what operation calculate. if the user chooses "Addition" it will show the two numeric input boxes (so they can input two numbers), if the user chooses "square" it will show only one numeric input box to square.
With this, I use conditionalPanel and if the condition is satisfied, it fetches through uiOutput() the numericInputs that I want. and same thing for square.
Now when I run this app, the conditional panels do not appear. Where did I go wrong? Thanks for checking out my question.
ui <- fluidPage( theme = shinytheme("slate"),
titlePanel("Basic Calculator"),
sidebarPanel(
selectInput("ops","Select what Operation use",choices = c("ADDITION","SQUARE")),
helpText("Please input the appropriate number depending on the operations"),
conditionalPanel("input.ops=='ADDITION'", uiOutput("var2")),
conditionalPanel("input.ops=='SQUARE'", uiOutput("var1"))
),#sidebar panel
)#fluidpage
server <- function(input, output) {
output$basicmath <- renderText( ifelse(input$ops=="ADDITION",input$a+input$b,
ifelse(input$ops=="SUBTRACTION",input$a-input$b,
ifelse(input$ops=="SQUARE",input$a*input$a,
ifelse(input$ops=="SQUARE ROOT",sqrt(input$a),
ifelse(input$ops=="MULTIPLICATION",input$a*input$b,"not a valid operation"))))),
output$var2 <- renderUI({
helpText("this will show to input two numerics to be added")
}) ,
output$var1 <- renderUI({
helpText("this will show to input one numeric to square")
})
)}
shinyApp(ui = ui, server = server)
The key issue you were having is that you put the uiOutputs inside the calculation output that you anticipated. It is better to separate them, since the calculation output won't run until it has the necessary prerequisite values (your input values). In addition, because you hadn't specified an output location for basicmath, the app didn't know where to put anything inside that call to renderText(). Below is working code that gets the right UI elements to appear.
One other thing you were missing in your renderUI was the use of tagList(). This helps ensure that all of your elements are packaged together, not just the last one.
Note that the math part does not work, but it looks like that was just a placeholder. When you do start to use it, be sure to use unique ids for each input. You have several instances of input$a and input$b, which probably isn't a workable approach.
library(shiny)
library(shinythemes)
ui <- fluidPage( theme = shinytheme("slate"),
titlePanel("Basic Calculator"),
sidebarPanel(
selectInput("ops","Select what Operation use",choices = c("ADDITION","SQUARE")),
helpText("Please input the appropriate number depending on the operations"),
conditionalPanel("input.ops=='ADDITION'", uiOutput("var2")),
conditionalPanel("input.ops=='SQUARE'", uiOutput("var1"))
),
mainPanel(
textOutput("basicmath")
)
)#fluidpage
server <- function(input, output) {
output$var2 <- renderUI({
tagList(
helpText("this will show to input two numerics to be added"),
splitLayout(
numericInput("var2a", label = "Input one number", value = NULL),
numericInput("var2b", label = "Input another number", value = NULL)
)
)
})
output$var1 <- renderUI({
tagList(
helpText("this will show to input one numeric to square"),
numericInput("var1a", label = "Input a number", value = NULL)
)
})
output$basicmath <- renderText( {ifelse(input$ops=="ADDITION",input$a+input$b,
ifelse(input$ops=="SUBTRACTION",input$a-input$b,
ifelse(input$ops=="SQUARE",input$a*input$a,
ifelse(input$ops=="SQUARE ROOT",sqrt(input$a),
ifelse(input$ops=="MULTIPLICATION",input$a*input$b,"not a valid operation")))))
})
}
shinyApp(ui = ui, server = server)
I am trying to find out how to show and hide my outputs like graphics and tabels each time when the user change something in the widgets. For instance I have a sliderInput for my variable called "gender" with 2 choices : male and female. I also have a button which executes estimations when the user click on it. I want to hide the outputs each time when the user changes at least one choice between the different widgets. For instance after one estimation the user decides to change only the level of education and when the user click on the sliderInput box, I would like to hide the previous results.
I tried to use the R package shinyjs and the functions hide/show but they are not working for outputs.
Do you have any idea how to do it without using shinyjs package?
Here is a part of my code:
shinyUI(fluidPage(
sidebarLayout(
fluidRow(
column(4, wellPanel(
fluidRow(
column(5,selectInput("gender",
label = div("Sexe",style = "color:royalblue"),
choices = list("Male", "Female"),
selected = "Female")),
# other different widjets..
column(8, plotOutput('simulationChange')),
column(4, tableOutput('simulationChangeTable'),
tags$style("#simulationChangeTable table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: 121px; margin-left:-30px;overflow:hidden; white-space:nowrap;text-align:left;align:left;}",
media="screen",
type="text/css"),
fluidRow(
column(6, tableOutput('simulationChangeEsperance'),
tags$style("#simulationChangeEsperance table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: -10px; margin-left:-30px;overflow:hidden; white-space:wrap;word-break: break-word;width:173px;text-align:left;}"))
)
)
)
)
)
))
shinyServer(function(input, output, session) {
# part of my server.R code
observe({
if (input$gender|input$age|input$birthplace|input$education){
shinyjs::hide("simulationChange")
shinyjs::hide("simulationChangeTable")
shinyjs::hide("simulationChangeEsperance")
}
})
Thank you.
The reason your code didn't work is because you didn't make a call to useShinyjs() (if you read the documentation or look at any examples of using shinyjs, you'll see that you HAVE to call useShinyjs() in the UI).
I couldn't replicate your code because it had too many errors, but just to demonstrate that it does work with outputs, here's a small example you can run. In your project, just add shinyjs::useShinyjs() somewhere in the UI.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("hideshow", "Hide/show plot"),
plotOutput("plot")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
plot(rnorm(100))
})
observeEvent(input$hideshow, {
# every time the button is pressed, alternate between hiding and showing the plot
toggle("plot")
})
}
shinyApp(ui = ui, server = server)
As mentioned by Dieter in the comments you need to use conditionalPanel. For example, in your ui.R, instead of
plotOutput('simulationChange')
use
conditionalPanel("output.show", plotOutput('simulationChange'))
And in your server.R add the following:
values <- reactiveValues()
values$show <- TRUE
observe({
input$gender
input$age
input$birthplace
input$education
values$show <- FALSE
})
output$show <- reactive({
return(values$show)
})
Also, don't forget to change values$show, when clicking on your button:
observeEvent(input$button, {
...
values$show <- TRUE
})
The other answers here don't seem to provide the right/complete answer. The solution is actually quite simple.
You need to use outputOptions(output, 'show', suspendWhenHidden = FALSE)
Below is a sample code that displays the text inside a conditionalPanel if the dropdown selection is 2 and hides if it is 1.
library(shiny)
ui <- fluidPage(
selectInput("num", "Choose a number", 1:2),
conditionalPanel(
condition = "output.show",
"The selected number is 2 so this text is displayed. Change it back to 1 to hide."
)
)
server <- function(input, output, session) {
output$show <- reactive({
input$num == 2 # Add whatever condition you want here. Must return TRUE or FALSE
})
outputOptions(output, 'show', suspendWhenHidden = FALSE)
}
shinyApp(ui = ui, server = server)
I am trying to find out how to show and hide my outputs like graphics and tabels each time when the user change something in the widgets. For instance I have a sliderInput for my variable called "gender" with 2 choices : male and female. I also have a button which executes estimations when the user click on it. I want to hide the outputs each time when the user changes at least one choice between the different widgets. For instance after one estimation the user decides to change only the level of education and when the user click on the sliderInput box, I would like to hide the previous results.
I tried to use the R package shinyjs and the functions hide/show but they are not working for outputs.
Do you have any idea how to do it without using shinyjs package?
Here is a part of my code:
shinyUI(fluidPage(
sidebarLayout(
fluidRow(
column(4, wellPanel(
fluidRow(
column(5,selectInput("gender",
label = div("Sexe",style = "color:royalblue"),
choices = list("Male", "Female"),
selected = "Female")),
# other different widjets..
column(8, plotOutput('simulationChange')),
column(4, tableOutput('simulationChangeTable'),
tags$style("#simulationChangeTable table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: 121px; margin-left:-30px;overflow:hidden; white-space:nowrap;text-align:left;align:left;}",
media="screen",
type="text/css"),
fluidRow(
column(6, tableOutput('simulationChangeEsperance'),
tags$style("#simulationChangeEsperance table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: -10px; margin-left:-30px;overflow:hidden; white-space:wrap;word-break: break-word;width:173px;text-align:left;}"))
)
)
)
)
)
))
shinyServer(function(input, output, session) {
# part of my server.R code
observe({
if (input$gender|input$age|input$birthplace|input$education){
shinyjs::hide("simulationChange")
shinyjs::hide("simulationChangeTable")
shinyjs::hide("simulationChangeEsperance")
}
})
Thank you.
The reason your code didn't work is because you didn't make a call to useShinyjs() (if you read the documentation or look at any examples of using shinyjs, you'll see that you HAVE to call useShinyjs() in the UI).
I couldn't replicate your code because it had too many errors, but just to demonstrate that it does work with outputs, here's a small example you can run. In your project, just add shinyjs::useShinyjs() somewhere in the UI.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("hideshow", "Hide/show plot"),
plotOutput("plot")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
plot(rnorm(100))
})
observeEvent(input$hideshow, {
# every time the button is pressed, alternate between hiding and showing the plot
toggle("plot")
})
}
shinyApp(ui = ui, server = server)
As mentioned by Dieter in the comments you need to use conditionalPanel. For example, in your ui.R, instead of
plotOutput('simulationChange')
use
conditionalPanel("output.show", plotOutput('simulationChange'))
And in your server.R add the following:
values <- reactiveValues()
values$show <- TRUE
observe({
input$gender
input$age
input$birthplace
input$education
values$show <- FALSE
})
output$show <- reactive({
return(values$show)
})
Also, don't forget to change values$show, when clicking on your button:
observeEvent(input$button, {
...
values$show <- TRUE
})
The other answers here don't seem to provide the right/complete answer. The solution is actually quite simple.
You need to use outputOptions(output, 'show', suspendWhenHidden = FALSE)
Below is a sample code that displays the text inside a conditionalPanel if the dropdown selection is 2 and hides if it is 1.
library(shiny)
ui <- fluidPage(
selectInput("num", "Choose a number", 1:2),
conditionalPanel(
condition = "output.show",
"The selected number is 2 so this text is displayed. Change it back to 1 to hide."
)
)
server <- function(input, output, session) {
output$show <- reactive({
input$num == 2 # Add whatever condition you want here. Must return TRUE or FALSE
})
outputOptions(output, 'show', suspendWhenHidden = FALSE)
}
shinyApp(ui = ui, server = server)
There are many questions about conditionalPanel in R shiny, but I still don't understand how I can use values created by server.R for conditionalPanel. Here is what I would like to do: I have a URL like http://some-url.com/php/session_check.php?sid=session_id. When the session_id starts with a 0, like http://some-url.com/php/session_check.php?sid=00221245 a string with a username is returned (e.g. 'testuser'). When the session_id starts with any other number but 0, like http://some-url.com/php/session_check.php?sid=10221245 a 0 is returned. Now I would like to hide a panel, depending on whether the a 0 or a username is returned. Therefore I try to do something like this:
conditionalPanel(
condition="output.disable_ui!=0"
I know that this is the wrong, but I don't really understand how the condition argument works for outputs, as the same would work if I would do this for any input from ui.R.
Here is my sample code:
server.R
library(shiny)
library(raster)
library(rgdal)
shinyServer(function(input, output, clientData) {
output$disable_ui<-reactive({
query<-parseQueryString(clientData$url_search)
url_path<-paste(sep="","http://some-url.com/php/session_check.php?sid=",query, collapse="")
read.table(url_path)
})
data <- reactive({
inFile <- input$example_layer
if (is.null(inFile))
return(NULL)
raster.file<- raster(inFile$datapath)
})
output$raster.plot <- renderPrint({
"Nothing to see here"
})
})
ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("test"),
sidebarPanel(
conditionalPanel(
condition="output.disable_ui!=0",
#File Upload
fileInput('example_layer', 'Choose Raster Layer (ASCII)', multiple=FALSE, accept='asc')
)),
mainPanel(
verbatimTextOutput("raster.plot")
)
))
#Julien Navarre is right: the output must be rendered. Except if you set its option suspendWhenHidden to FALSE:
output$disable_ui<-reactive({
query<-parseQueryString(clientData$url_search)
url_path<-paste(sep="","http://some-url.com/php/session_check.php?sid=",query, collapse="")
read.table(url_path)
})
outputOptions(output, 'disable_ui', suspendWhenHidden=FALSE)
I think that the output must be rendered in the UI if you want to use it after in the condition of a conditionalPanel.
With you example, the HTML for the conditional panel will look like something like this :
<div data-display-if="output.disable_ui!=0">
If no elements in your page (created as outputs in the server side) have the id "disable_ui" then the condition "output.disable_ui!=0" is always TRUE, and the conditional panel always displayed.
A simple example :
shiny::runApp(list(
ui = pageWithSidebar(
headerPanel("test"),
sidebarPanel(
selectInput(
"var", "Var",
0:9)),
mainPanel(
verbatimTextOutput("id"),
conditionalPanel(
condition="output.id!=0",
h4('Visible')
)
)
),
server = function(input, output) {
output$id<-reactive({input$var})
}
))
If you select a number different of 0 the conditional panel will be displayed.
Now, comment the line verbatimTextOutput("id"),, there is no more element with the id "id" in the page and then the condition of the conditional panel <div data-display-if="output.id!=0"> can't be FALSE.
This is the real answer to this question:
Use this inside of your server function:
outputOptions(output, "outputId", suspendWhenHidden = FALSE)
You will then be able to use the output.item in your conditionalPanel.
Answer from here:
https://github.com/daattali/advanced-shiny/blob/master/server-to-ui-variable/app.R
And here:
https://github.com/rstudio/shiny/issues/1318