Input widgets
What does the server receive?
Every input widget has the same first two arguments:
- 1
-
How the server calls it:
input$id - 2
- What the user reads
- 3
- Widget-specific options (choices, min, max, starting value…)
What changes from widget to widget is what arrives in input$id: a number, a text, a vector, a date, a data frame…
In all the apps on this page, the server prints the class and the structure (str()) of each input, so you can see exactly what it receives. Play with the widgets and watch the boxes on the right.
Choosing from a list
#| '!! shinylive warning !!': |
#| shinylive does not work in self-contained HTML documents.
#| Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 560
## file: ui.R
library(shiny)
ui <- fluidPage(
fluidRow(
column(6, selectInput("sel", "selectInput()",
choices = c("rock", "pressure", "cars"))),
column(6, verbatimTextOutput("sel_out"))
),
fluidRow(
column(6, selectInput("sel_named", "selectInput() with named choices",
choices = c("rock" = 1, "pressure" = 2, "cars" = 3))),
column(6, verbatimTextOutput("sel_named_out"))
),
fluidRow(
column(6, selectInput("sel_multi", "selectInput(multiple = TRUE)",
choices = c("A", "B", "C"), multiple = TRUE)),
column(6, verbatimTextOutput("sel_multi_out"))
),
fluidRow(
column(6, radioButtons("radio", "radioButtons()",
choices = c("Low" = "low", "High" = "high"))),
column(6, verbatimTextOutput("radio_out"))
),
fluidRow(
column(6, checkboxGroupInput("group", "checkboxGroupInput()",
choices = c("A", "B", "C"))),
column(6, verbatimTextOutput("group_out"))
)
)
## file: server.R
library(shiny)
# helper: print the class and the structure of an object
inspect <- function(x) {
cat("class:", class(x), "\n")
str(x)
}
server <- function(input, output, session) {
output$sel_out <- renderPrint(inspect(input$sel))
output$sel_named_out <- renderPrint(inspect(input$sel_named))
output$sel_multi_out <- renderPrint(inspect(input$sel_multi))
output$radio_out <- renderPrint(inspect(input$radio))
output$group_out <- renderPrint(inspect(input$group))
}
- With named choices (
"rock" = 1) the user sees the name, the server receives the value, and the value is always text:"1", not1 multiple = TRUEandcheckboxGroupInput()return a vector, andNULLwhen nothing is selected
Numbers and text
#| '!! shinylive warning !!': |
#| shinylive does not work in self-contained HTML documents.
#| Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 480
## file: ui.R
library(shiny)
ui <- fluidPage(
fluidRow(
column(6, sliderInput("slider", "sliderInput()",
min = 0, max = 100, value = 50)),
column(6, verbatimTextOutput("slider_out"))
),
fluidRow(
column(6, sliderInput("range", "sliderInput() with a range",
min = 0, max = 100, value = c(20, 80))),
column(6, verbatimTextOutput("range_out"))
),
fluidRow(
column(6, numericInput("num", "numericInput()",
value = 10, min = 0, max = 100, step = 0.5)),
column(6, verbatimTextOutput("num_out"))
),
fluidRow(
column(6, textInput("text", "textInput()", value = "hello")),
column(6, verbatimTextOutput("text_out"))
)
)
## file: server.R
library(shiny)
inspect <- function(x) {
cat("class:", class(x), "\n")
str(x)
}
server <- function(input, output, session) {
output$slider_out <- renderPrint(inspect(input$slider))
output$range_out <- renderPrint(inspect(input$range))
output$num_out <- renderPrint(inspect(input$num))
output$text_out <- renderPrint(inspect(input$text))
}
- If you give
sliderInput()two starting values, you get a range: a vector of length 2 - Delete the number in
numericInput(): the server receivesNA textInput()always returns text, also when the user types42
Yes/no and dates
#| '!! shinylive warning !!': |
#| shinylive does not work in self-contained HTML documents.
#| Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 380
## file: ui.R
library(shiny)
ui <- fluidPage(
fluidRow(
column(6, checkboxInput("check", "checkboxInput()", value = FALSE)),
column(6, verbatimTextOutput("check_out"))
),
fluidRow(
column(6, dateInput("date", "dateInput()")),
column(6, verbatimTextOutput("date_out"))
),
fluidRow(
column(6, dateRangeInput("dates", "dateRangeInput()")),
column(6, verbatimTextOutput("dates_out"))
)
)
## file: server.R
library(shiny)
inspect <- function(x) {
cat("class:", class(x), "\n")
str(x)
}
server <- function(input, output, session) {
output$check_out <- renderPrint(inspect(input$check))
output$date_out <- renderPrint(inspect(input$date))
output$dates_out <- renderPrint(inspect(input$dates))
}
Files
#| '!! shinylive warning !!': |
#| shinylive does not work in self-contained HTML documents.
#| Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 330
## file: ui.R
library(shiny)
ui <- fluidPage(
fileInput("file", "fileInput(): upload any CSV file", accept = ".csv"),
verbatimTextOutput("file_out")
)
## file: server.R
library(shiny)
inspect <- function(x) {
cat("class:", class(x), "\n")
str(x)
}
server <- function(input, output, session) {
output$file_out <- renderPrint(inspect(input$file))
}
No CSV at hand? Use example.csv.
input$file is not the data: it is a small data frame describing the file (name, size, type) and, most importantly, datapath, the place where Shiny saved a copy of it. To read the data you use it like any path:
read.csv(input$file$datapath)Before the upload, input$file is NULL.
Cheat sheet
| Widget | input$id contains |
Class |
|---|---|---|
selectInput(), radioButtons() |
the value of the selected choice | character (always) |
selectInput(multiple = TRUE), checkboxGroupInput() |
the selected values, NULL if none |
character vector |
sliderInput() |
a number (two numbers for a range) | numeric/integer |
numericInput() |
a number, NA if empty |
numeric/integer |
textInput() |
the text, "" if empty |
character |
checkboxInput() |
TRUE/FALSE |
logical |
dateInput(), dateRangeInput() |
one / two dates | Date |
actionButton() |
how many times it was clicked | counter (integer) |
fileInput() |
NULL, then name, size and datapath of the file |
data.frame |
The complete list, with code, is in the Shiny widget gallery.
Your turn
Without running anything, what does the server receive in these cases?
selectInput("n", "Rows", choices = c("five" = 5, "ten" = 10)), the user picks tencheckboxGroupInput("v", "Variables", choices = c("x", "y")), the user picks nothingsliderInput("s", "Range", min = 1, max = 10, value = c(2, 5))
Check your answers by pasting the widgets in one of the apps above.
"10": a text, not a number. To use it as a number:as.numeric(input$n)NULLc(2, 5):input$s[1]is the minimum,input$s[2]the maximum
In my-shiny-app, add a sliderInput() with ID "n" (from 1 to 10) to ui.R, and a second verbatimTextOutput() with ID "n_out". In server.R, print input$n * 2 in it. Run the app.
# ui.R
ui <- fluidPage(
selectInput(inputId = "mySelection", label = h3("Select box"),
choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3),
selected = 1),
verbatimTextOutput(outputId = "myOutput"),
sliderInput(inputId = "n", label = "Pick a number", min = 1, max = 10, value = 5),
verbatimTextOutput(outputId = "n_out")
)# server.R
server <- function(input, output, session) {
output$myOutput <- renderPrint({
paste("This is my choice:", input$mySelection)
})
output$n_out <- renderPrint({
input$n * 2
})
}