Shiny and Database Integration
Source:vignettes/shiny-and-database-integration.Rmd
shiny-and-database-integration.Rmd
- Seamlessly embed SurveyJS forms in Shiny apps.
- Capture, update, and persist survey responses—including live editing and database storage.
- For custom JS hooks or frontend logic, see the Advanced JS Hooks & Events vignette.
Table of Contents
- Minimal Shiny Survey App
- Live Mode: Real-Time Updates
- Dynamic Updates: Update Survey from Server
- Saving and Loading Responses with a Database
- Common Pitfalls & Further Reference
Minimal Shiny Survey App
library(shiny)
library(rsurveyjs)
ui <- fluidPage(
surveyjsOutput("mysurvey"),
verbatimTextOutput("result")
)
server <- function(input, output, session) {
output$mysurvey <- renderSurveyjs({
surveyjs(
schema = list(
title = "Feedback",
questions = list(
list(type = "text", name = "name", title = "What is your name?"),
list(type = "rating", name = "rating", title = "How would you rate us?")
)
)
)
})
output$result <- renderPrint({
input$mysurvey_data
})
}
shinyApp(ui, server)
Live Mode: Real-Time Updates
Use live = TRUE
to get continuous feedback as the user
fills out the form.
ui <- fluidPage(
surveyjsOutput("mysurvey"),
verbatimTextOutput("live_output")
)
server <- function(input, output, session) {
output$mysurvey <- renderSurveyjs({
surveyjs(
schema = list(
title = "Live Feedback",
questions = list(
list(type = "text", name = "comment", title = "Your comment?")
)
),
live = TRUE
)
})
output$live_output <- renderPrint({
input$mysurvey_data_live
})
}
shinyApp(ui, server)
- Use
input$<id>_data_live
for live data. - Use
input$<id>_data
for final, completed responses.
Dynamic Updates: Update Survey from Server
Use updateSurveyjs()
to change schema, initial data,
theme, or locale on the fly.
ui <- fluidPage(
surveyjsOutput("mysurvey"),
actionButton("reload", "Switch Survey")
)
server <- function(input, output, session) {
output$mysurvey <- renderSurveyjs({
surveyjs(
schema = list(
title = "First Survey",
questions = list(
list(type = "text", name = "favorite", title = "Favorite color?")
)
)
)
})
observeEvent(input$reload, {
updateSurveyjs(session, "mysurvey", schema = list(
title = "New Survey",
questions = list(
list(type = "rating", name = "satisfaction", title = "Rate your satisfaction")
)
))
})
}
shinyApp(ui, server)
Saving and Loading Responses with a Database
Here’s a minimal example using DBI and SQLite for persistent storage.
library(DBI)
library(RSQLite)
library(shiny)
library(rsurveyjs)
# Set up database connection (for demo: use temp file)
con <- dbConnect(RSQLite::SQLite(), "responses.sqlite")
if (!dbExistsTable(con, "survey_results")) {
dbExecute(con, "CREATE TABLE survey_results (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT,
name TEXT,
rating INTEGER
)")
}
ui <- fluidPage(
surveyjsOutput("mysurvey"),
actionButton("save", "Save Response"),
tableOutput("responses")
)
server <- function(input, output, session) {
output$mysurvey <- renderSurveyjs({
surveyjs(
schema = list(
title = "Feedback",
questions = list(
list(type = "text", name = "name", title = "Your name?"),
list(type = "rating", name = "rating", title = "Rate us")
)
)
)
})
observeEvent(input$save, {
dat <- input$mysurvey_data
if (!is.null(dat)) {
dbExecute(con, "INSERT INTO survey_results (timestamp, name, rating) VALUES (?, ?, ?)",
params = list(Sys.time(), dat$name, dat$rating)
)
}
})
output$responses <- renderTable({
dbGetQuery(con, "SELECT * FROM survey_results ORDER BY id DESC")
})
}
onStop(function() dbDisconnect(con))
shinyApp(ui, server)
- Replace
"responses.sqlite"
with your desired file path or use another DBI-compatible backend. - For production, sanitize and validate inputs appropriately.
Common Pitfalls & Further Reference
-
Input IDs:
-
input$mysurvey_data
is the completed form data.
-
input$mysurvey_data_live
is live-updating data (whenlive = TRUE
).
-
-
Missing responses:
- Always check
is.null(input$mysurvey_data)
before saving. - Ensure the survey “Complete” button is clicked to trigger saving.
- Always check
-
More advanced features:
- See Advanced JS Hooks & Events to react to completion or validation in the frontend.
- Further Reading: