The goal of this package is to integrate SurveyJS with Shiny to interface with a PostgreSQL database and create dynamic user experiences.
SurveyJS is a JavaScript library that streamlines the creation of survey applications through a jQuery architecture. The library offers a visual editor to design complex surveys through a drag-and-drop interface and generate a JSON object.
The JSON defines every survey element, including a title, description, logo, and page layout as well as progress indicators, question types, validation rules, logic flows, visibility controls, and text piping. The library's strength lies in its backend-agnostic approach, supporting integration with any server technology.
In R & Shiny applications, developers can parse the JSON either as a raw text string or by converting a list to JSON format, which then gets passed to the front-end. LLMs are great tool for converting a JSON object to a list.
-
Store data in a PostgreSQL database, including timing metadata (duration to load, duration to complete, duration to save, date created, and date updated) and tracking metadata (Shiny session ID and IP address)
-
All of the database tables that the app writes to are automatically created if they don't already exist.
-
Automatically save survey progress as cookies and resume later
-
Change the theme, primary color, and contrast mode (light or dark)
-
Dynamically populate field choices (i.e., response options) from a database table and create dependent inputs (e.g., select a package name and filter available versions) with support for tracking via URL parameters (e.g., referral source; see vignette)
-
Log app messages, warnings, and errors in a database table
-
Use future to update tables without interrupting the survey
pak::pkg_install("dylanpieper/shinysurveyjs")
Imagine I want to develop a feedback survey for my package.
Let's define the survey as a list and then run the survey()
function. I'm using Supabase for my PostgreSQL database.
survey <- list(
title = "R Package Feedback",
pages = list(
list(
name = "page1",
elements = list(
list(
type = "matrix",
name = "rating",
title = "Please rate the shinysurveyjs 📦:",
columns = list(
list(value = "1", text = "Bad"),
list(value = "2", text = "Neutral"),
list(value = "3", text = "Good")
),
rows = list(
list(value = "UI", text = "UI Design"),
list(value = "Server", text = "Server Functionality")
)
),
list(
type = "comment",
name = "feedback",
title = "Any other feedback?"
)
)
)
)
)
shinysurveyjs::survey(
list = survey,
db_config = list(
host = Sys.getenv("HOST"), # aws-0-us-east-2.pooler.supabase.com
port = as.numeric(Sys.getenv("PORT")), # 5432
db_name = Sys.getenv("DB_NAME"), # postgres
user = Sys.getenv("USER"), # username
password = Sys.getenv("PASSWORD"), # password
write_table = Sys.getenv("WRITE_TABLE"), # survey_package_feedback
log_table = Sys.getenv("LOG_TABLE") # survey_app_logs
)
)
By default, the database configuration looks for environmental variables (e.g., Sys.getenv("PASSWORD")
) that can be loaded from the .Renviron
or your preferred method for handling environmental variables.
Check out a more complex gist of this form with expressions and text piping.