--- title: "Conditional controls and screen output" author: "Julien Barnier" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Conditional controls and screen output} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Conditional controls Sometimes you don't want your user to be able to go to the next screen if a condition based on inputs is not met. This can be done in `shinyglide` with the `next_condition` argument of the `screen` function. This option takes exactly the same syntax has the one used in `shiny::conditionalPanel`. For example, in the following app, the *Next* button is disabled until the *n* value is greater then zero : ```{r eval = FALSE} ui <- fluidPage( glide( screen( next_condition = "input.n > 0", p("Please choose a value for n :"), numericInput("n", "n :", value = 0) ), screen( p("Here is your plot :"), plotOutput("plot") ) ) ) server <- function(input, output, session) { output$plot <- renderPlot({ hist(rnorm(input$n), main = paste("n =", input$n)) }) } shinyApp(ui, server) ``` You can do the same for the *Back* button with the `previous_condition` argument. By default the button is disabled when the condition is not met (more precisely, the button gets a `disabled = "disabled"` argument and a `disabled` CSS class). If you prefer to hide it entirely, you can add `disable_type = "hide"` to your `glide()` definition : ```{r eval = FALSE} ui <- fluidPage( glide( disable_type = "hide", screen( next_condition = "input.n > 0", p("Please choose a value for n :"), numericInput("n", "n :", value = 0) ), screen( p("Here is your plot :"), plotOutput("plot") ) ) ) server <- function(input, output, session) { output$plot <- renderPlot({ hist(rnorm(input$n), main = paste("n =", input$n)) }) } shinyApp(ui, server) ``` ## Screen output Sometimes you want to show a screen only if certain conditions are met based on inputs. For example, if a user chooses a value which is not present in a dataset, you would like to display a specific screen to alert him. This is possible by using a `screenOutput` call in you app UI, associated to a `renderUI` in your app server. If `renderUI` returns `NULL`, the screen will be hidden. Here is an example : ```{r eval = FALSE} ui <- fluidPage( glide( disable_type = "hide", screen( p("Do you want to see the next screen ?"), checkboxInput("check", "Yes, of course !", value = FALSE) ), screenOutput("check_screen"), screen( p("And this is the last screen") ) ) ) server <- function(input, output, session) { output$check_screen <- renderUI({ if(!input$check) return(NULL) p("Here it is !") }) outputOptions(output, "check_screen", suspendWhenHidden = FALSE) } shinyApp(ui, server) ``` **Important :** for the `screenOutput` to work, it is mandatory to add the following line in your app server : ```{r eval=FALSE} outputOptions(output, "your_screen_id", suspendWhenHidden = FALSE) ``` Otherwise, it won't be updated when hidden. Sometimes the `screenOutput` computation takes some time. In these cases, with the default controls, the *Next* button is disabled and a *Loading* message is shown until the next screens computations is done. You can see it in the following example, which is the same as the previous one but with an articial 2 seconds waiting time : ```{r eval = FALSE} ui <- fluidPage( glide( disable_type = "hide", screen( p("Do you want to see the next screen ?"), checkboxInput("check", "Yes, of course !", value = FALSE) ), screenOutput("check_screen"), screen( p("And this is the last screen") ) ) ) server <- function(input, output, session) { output$check_screen <- renderUI({ Sys.sleep(2) if(!input$check) return(NULL) p("Here it is !") }) outputOptions(output, "check_screen", suspendWhenHidden = FALSE) } shinyApp(ui, server) ``` ### Customizing loading You can customize the loading label and animation with options passed to `glide()` : - `loading_class` (default value : `"loading"`) : a CSS class passed to the *Next* button when in loading state - `loading_label` : the label of the *Next* button while in loading state. This can be any HTML, and you can insert a `span(class = "shinyglide-spinner")` in it if you want to display the defautl animated spinner somewhere. You can take a look at the [custom controls sample app](https://github.com/juba/shinyglide/tree/master/inst/examples/04_custom_controls) for an example of loading customization with [custom controls](https://juba.github.io/shinyglide/articles/c_custom_controls.html) and CSS.