The shinyFeedback
package displays user friendly messages that appear along side shiny
inputs. e.g.
shinyFeedback
currently works with the following shiny::*Input()
functions:
shiny::dateInput()
shiny::dateRangeInput()
shiny::numericInput()
shiny::passwordInput()
shiny::selectInput()
shiny::sliderInput()
shiny::textAreaInput()
shiny::textInput()
shinyWidgets::airDatePickerInput()
shinyWidgets::pickerInput()
In order to use shinyFeedback
you need to include the useShinyFeedback()
function at the top of your UI.
The following is a minimal example of a shiny
app that uses shinyFeedback
. Run the following code in your R console to run the app.
library(shiny)
library(shinyFeedback)
ui <- fluidPage(
useShinyFeedback(), # include shinyFeedback
textInput(
"myInput",
"Warn if >3 characters",
value = ""
)
)
server <- function(input, output, session) {
observeEvent(input$myInput, {
if (nchar(input$myInput) > 3) {
showFeedbackWarning(
inputId = "myInput",
text = "too many chars"
)
} else {
hideFeedback("myInput")
}
})
}
shinyApp(ui, server)
The above app has one textInput()
input in the UI. In the server function, we write the code to conditionally display a feedback message. If the text input has more than 3 characters, the feeback message is displayed.
feedback()
The feedback()
function is an alternative to using showFeedback()
and hideFeedback()
. With feedback()
the feedback message is shown/hidden based on whether the show
argument to feedback()
is “truthy”. “truthiness” is determined by shiny::isTruthy()
. feedback()
works nicely with reactive expressions that use shiny::req()
to check the validity of Shiny inputs. e.g.
library(shiny)
library(shinyFeedback)
ui <- fluidPage(
useShinyFeedback(), # include shinyFeedback
selectInput(
"dataset",
"Dataset",
choices = c(
"airquality",
"Unknown dataset"
)
),
tableOutput('data_table')
)
server <- function(input, output, session) {
data_out <- reactive({
req(input$dataset)
dataset_exists <- exists(input$dataset, "package:datasets")
feedbackWarning("dataset", !dataset_exists, "Unknown dataset")
req(dataset_exists, cancelOutput = TRUE)
get(input$dataset, "package:datasets")
})
output$data_table <- renderTable({
head(data_out())
})
}
shinyApp(ui, server)
shinyFeedback works inside shiny modules.
As for all modules, input and output IDs in the module UI code must be wrapped in shiny::ns()
calls. Inside your module server code, you need not wrap input or output IDs inside shiny::ns()
; shinyFeedback will automatically prepend the namespace of your current module.
Here is a simple example using shinyFeedback inside a module:
library(shiny)
library(shinyFeedback)
numberInput <- function(id) {
ns <- NS(id)
tagList(
useShinyFeedback(), # inclusion here is ideal; b/c inside module
numericInput(
ns("warningInput"),
"Warn if Negative",
value = 0
)
)
}
number <- function(input, output, session) {
observeEvent(input$warningInput, {
req(input$warningInput)
if (input$warningInput < 0) {
showFeedbackWarning(inputId = "warningInput")
} else {
hideFeedback("warningInput")
}
})
}
ui <- fluidPage(
numberInput(id = "numberFoo")
)
server <- function(input, output) {
callModule(module = number, id = "numberFoo")
}
shinyApp(ui, server)