Reputation: 43
I am having difficulty triggering an alert in a Shiny app that I have created. The app itself is very simple, and displays one slider with numbers and a line plot. However, I would like for an alert to be triggered whenever the slider is set to a value above 5. Here is the code:
UI
library(shiny)
library(shinythemes)
library(shinyBS)
shinyUI(fluidPage(theme = shinytheme("superhero"),
tags$head(
tags$style(HTML("
.shiny-output-error-validation {
color: green;
}
"))
),
sidebarLayout(
sidebarPanel(
sliderInput("samplestat",
"Value:",
min = 1,
max = 10,
value = 1)
),
mainPanel(
h3("Graph", style = "font-family: 'Jura'; color: blue; font-size: 32px;"),
HTML("<p>Graph</p>"),
plotOutput("LinePlot")
)
)
))
SERVER
library(shiny)
library(ggplot2)
library(scales)
samplestat <- function(input) {
if (input > 5) {
"Choose another value. samplestat must be below 5!"
} else if (input < 4) {
FALSE
} else {
NULL
}
}
shinyServer(function(input, output) {
data <- reactive({
validate(
need(input$data != "", "Please select a value below 5")
)
get(input$data)
})
output$LinePlot <- renderPlot({
n=1:10
samplestat <- seq(min(n), max(n), length.out = input$samplestat)
plot(samplestat, type = "o", col = 'blue', border = 'white', xlab="X Axis", ylab ="Y Axis")
}
)
})
When I run this code, the line and slider displays, but I do not get any alert when I slide the slider to a value above 5. I am not sure if I am possibly using validate-need incorrectly, or whether I have overlooked something else.
Upvotes: 1
Views: 5576
Reputation: 13128
You should place validate(...)
insider renderPlot({...})
. That is, your server.R
should be something like:
function(input, output) {
output$LinePlot <- renderPlot({
validate(
need(input$samplestat <= 5, "Please select a value below 5")
)
n <- 1:10
samplestat <- seq(min(n), max(n), length.out = input$samplestat)
plot(samplestat, type = "o", col = 'blue',
fg = 'white', xlab= "X Axis", ylab = "Y Axis")
})
}
Note that there should be no problem with wrapping your validation code in a reactive function. Suppose your function to test for a condition is
validate_samplestat <- function(input) {
if (input > 5) {
"Choose another value. samplestat must be below 5!"
} else {
NULL
}
}
You can wrap this in reactive
in your main server function, and place the reactive function in your output rendering function. The main thing is to place the bit of code that calls validate
in your output rendering function:
function(input, output) {
v <- reactive({
validate(validate_samplestat(input$samplestat))
})
output$LinePlot <- renderPlot({
v() # <--- validate here
n <- 1:10
samplestat <- seq(min(n), max(n), length.out = input$samplestat)
plot(samplestat, type = "o", col = 'blue',
fg = 'white', xlab= "X Axis", ylab = "Y Axis")
})
}
Upvotes: 4