Title: | Markdown-Based Programmable Surveys Using 'Quarto' and 'shiny' |
Version: | 0.12.6 |
Description: | Generate programmable surveys using markdown and R code chunks. Surveys are composed of two files: a survey.qmd 'Quarto' file defining the survey content (pages, questions, etc), and an app.R file defining a 'shiny' app with global settings (libraries, database configuration, etc.) and server configuration options (e.g., conditional skipping / display, etc.). Survey data collected from respondents is stored in a 'PostgreSQL' database. Features include controls for conditional skip logic (skip to a page based on an answer to a question), conditional display logic (display a question based on an answer to a question), a customizable progress bar, and a wide variety of question types, including multiple choice (single choice and multiple choices), select, text, numeric, multiple choice buttons, text area, and dates. Because the surveys render into a 'shiny' app, designers can also leverage the reactive capabilities of 'shiny' to create dynamic and interactive surveys. |
License: | MIT + file LICENSE |
URL: | https://pkg.surveydown.org |
BugReports: | https://github.com/surveydown-dev/surveydown/issues |
Depends: | R (≥ 4.1.0) |
Imports: | bslib, cli, DBI, dotenv, DT, fs, htmltools, jsonlite, markdown, miniUI, pool, quarto, RPostgres, rstudioapi, rvest, shiny, shinyjs, shinyWidgets, utils, xml2, yaml |
Suggests: | glue, knitr, leaflet, testthat |
Encoding: | UTF-8 |
RoxygenNote: | 7.3.2 |
NeedsCompilation: | no |
Packaged: | 2025-07-07 13:12:02 UTC; jhelvy |
Author: | John Paul Helveston
|
Maintainer: | John Paul Helveston <john.helveston@gmail.com> |
Repository: | CRAN |
Date/Publication: | 2025-07-07 13:30:02 UTC |
Add a Page Template to the Current Document
Description
This function inserts a template for a surveydown page at the current cursor position in the active RStudio document. It provides a basic structure for a new page, including a title, content area, and a next button. If the function call exists in the document, it will be removed before inserting the template.
Usage
sd_add_page(page_id = "page_id")
Arguments
page_id |
A character string specifying the ID for the page. Defaults to "page_id". |
Details
IMPORTANT: This function should be run outside any division or R code chunk in your 'Quarto' document. Running it inside a division or code chunk may result in an incorrect page structure.
The function performs the following steps:
Checks for and removes any existing
sd_add_page()
function call in the document.Inserts a template at the current cursor position.
The template includes:
A div with class
'sd-page'
and the specified page IDA placeholder for the page title
A placeholder for page contents
An R code chunk with a placeholder for questions and a next button
Special page_id values:
When page_id is "end", a thank-you page template with
sd_close()
is inserted
Value
This function does not return a value. It modifies the active document as a side effect by inserting text and potentially removing a function call.
Examples
if (interactive()) {
library(surveydown)
# Insert a new page template with default ID
sd_add_page()
# Insert a new page template with custom ID
sd_add_page(page_id = "welcome")
# Insert an end/thank you page
sd_add_page(page_id = "end")
}
Add a Question Template to the Current Document
Description
This function inserts a template for a surveydown question at the current cursor position in the active RStudio document. It supports various question types and automatically removes the function call before inserting the template if it exists in the document.
Usage
sd_add_question(type = "mc", id = NULL, label = NULL, chunk = FALSE)
Arguments
type |
A character string specifying the type of question template to
insert.
Default is
|
id |
A character string specifying the ID for the question. If not provided, a default ID based on the question type will be used. This ID should be unique within your survey. |
label |
A character string specifying the label (question text) to display to respondents. If not provided, a default label placeholder will be used. |
chunk |
Logical. If |
Details
The function performs the following steps:
Checks for and removes any existing
sd_add_question()
function call in the document.Inserts the appropriate question template at the current cursor position.
If an ID is provided, replaces the default ID in the template with the provided ID.
If a label is provided, replaces the default label in the template with the provided label.
Value
This function does not return a value. It modifies the active document as a side effect by inserting text and potentially removing a function call.
Examples
if (interactive()) {
library(surveydown)
# Insert a default multiple choice question template
sd_add_question()
# Insert a text input question with custom ID and label
sd_add_question("text", id = "user_email", label = "What is your email address?")
# Insert a slider question template
sd_add_question("slider", id = "satisfaction", label = "How satisfied were you with our service?")
}
Create a 'Close' Button to Exit the Survey
Description
This function creates a 'Close' button that, when clicked, will trigger the exit process for the survey. Depending on the server-side configuration, this may show a rating question or a simple confirmation dialog before attempting to close the current browser tab or window.
Usage
sd_close(label = NULL)
Arguments
label |
Character string. The label of the 'Close' button. Defaults to
|
Details
The function generates a 'shiny' action button that, when clicked, triggers
the 'show_exit_modal' event. The server-side logic (controlled by the
rate_survey
parameter in sd_server()
) determines whether to show a
rating question or a simple confirmation dialog.
The function also includes a custom message handler for closing the window. This is necessary because some browsers may not allow JavaScript to close windows that were not opened by JavaScript. In such cases, the user will be prompted to close the tab manually.
Value
A 'shiny' tagList containing the 'Close' button UI element and associated JavaScript for the exit process.
Note
The actual behavior of the exit process (whether to show a rating
question or not) is controlled by the rate_survey
parameter in the
sd_server()
function, not in this UI function.
See Also
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_close.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Generate a Random Completion Code
Description
This function generates a random completion code with a specified number of digits. The code is returned as a character string.
Usage
sd_completion_code(digits = 6)
Arguments
digits |
An integer specifying the number of digits in the completion code. Must be a positive integer. Default is 6. |
Value
A character string representing the random completion code.
Examples
library(surveydown)
sd_completion_code() # generates a 6-digit code
sd_completion_code(digits = 8) # generates an 8-digit code
sd_completion_code(digits = 4) # generates a 4-digit code
sd_completion_code(digits = 10) # generates a 10-digit code
Create a copy of a value
Description
This function creates a copy of an input value and makes it available as a
new output. The new output can then be displayed using sd_output()
.
Usage
sd_copy_value(id, id_copy)
Arguments
id |
Character string. The ID of the input value to copy. |
id_copy |
Character string. The ID for the new copy (must be different
from |
Value
NULL
invisibly. This function is called for its side effects.
See Also
sd_output()
for displaying the copied value
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_ui.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "sd_copy_value.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
# Make a copy of the "name" variable to call its value a second time
sd_copy_value(id = "name", id_copy = "name_copy")
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Create a new survey template
Description
This function creates a new survey template by copying template files to the specified directory. You can choose from various predefined templates, including the default built-in template and specialized templates from the surveydown-dev/templates repository.
Usage
sd_create_survey(template = "default", path = getwd(), ask = TRUE)
Arguments
template |
A character string specifying the template to use. Default is "default" which uses the built-in package template. Other options include:
|
path |
A character string specifying the directory where the survey template should be created. Defaults to the current working directory. |
ask |
Logical. If |
Details
When creating a new survey template, this function will:
Check if the specified template is valid
Confirm the destination path with the user (if it's the current directory)
Download template files from GitHub if a non-default template is specified
Copy template files to the destination directory
Skip .Rproj files if one already exists in the destination
Prompt for confirmation before overwriting existing files
External templates are downloaded from the surveydown-dev/templates GitHub repository.
Value
Invisible NULL
. The function is called for its side effects.
Examples
if (interactive()) {
# Create a survey with the "question_types" template in the "my_survey" directory
sd_create_survey(template = "question_types", path = "my_survey")
# Create a survey using the default template in the "my_survey" directory
sd_create_survey(path = "my_survey")
# Create a survey with default template in current directory
sd_create_survey("default")
# Create a survey without asking for confirmation
sd_create_survey(template = "default", path = "my_survey", ask = FALSE)
}
Create a translations template file
Description
This function creates a template translations.yml file in the project root directory that users can customize to modify system messages.
Usage
sd_create_translations(language = "en", path = getwd())
Arguments
language |
Character string specifying the language to use. See
https://shiny.posit.co/r/reference/shiny/1.7.0/dateinput for supported
languages. Also, if |
path |
Character string specifying the directory where the translations.yml file should be created. Defaults to the current working directory. The file should be placed in the root project folder of your surveydown survey. |
Value
Invisible NULL
.
Examples
if (interactive()) {
# Create English template
sd_create_translations()
# Create German template
sd_create_translations(language = "de")
# Create Japanese template
# Will use English messages but Japanese date picker - user can modify
# the messages as desired
sd_create_translations(language = "ja")
}
Launch Survey Dashboard
Description
This function creates a comprehensive dashboard for survey data analysis with two main tabs:
Dashboard: Displays survey statistics, response trends, and a full response data table
Settings: Provides interface for updating database connection settings
Usage
sd_dashboard(gssencmode = "auto")
Arguments
gssencmode |
Character string. The GSS encryption mode for the database
connection. Defaults to
|
Details
Opens an interactive dashboard to view and analyze survey responses using a Shiny dashboard interface.
The dashboard offers the following features:
Summary value boxes showing total responses, daily average, completion rate, and average rating
Response trend plot with daily and cumulative responses
Downloadable survey responses data table
Database connection configuration and testing
Value
Launches a Shiny application with the survey dashboard. The function does not return a value; it is called for its side effects of opening the dashboard interface.
Examples
## Not run:
# Launch the survey dashboard with default settings
sd_dashboard()
# Launch with disabled GSS encryption (for VPN connections)
sd_dashboard(gssencmode = "disable")
## End(Not run)
Connect to a 'PostgreSQL' Database with Automatic Cleanup
Description
This function establishes a connection pool to a 'PostgreSQL' database (e.g. Supabase) and sets up automatic cleanup when the 'shiny' session ends.
Usage
sd_database(
host = NULL,
dbname = NULL,
port = NULL,
user = NULL,
table = NULL,
password = Sys.getenv("SURVEYDOWN_PASSWORD"),
gssencmode = "prefer",
ignore = FALSE,
min_size = 1,
max_size = Inf
)
Arguments
host |
Character string. The host address of the PostgreSQL database. |
dbname |
Character string. The name of the PostgreSQL database. |
port |
Integer. The port number for the PostgreSQL database connection. |
user |
Character string. The username for the PostgreSQL database connection. |
table |
Character string. The name of the table to interact with in the Supabase database. |
password |
Character string. The password for the PostgreSQL database
connection. NOTE: While you can provide a hard-coded password here, we do
NOT recommend doing so for security purposes. Instead, you should establish
a password with |
gssencmode |
Character string. The GSS encryption mode for the database
connection. Defaults to |
ignore |
Logical. If |
min_size |
Integer. The minimum number of connections in the pool. Defaults to 1. |
max_size |
Integer. The maximum number of connections in the pool.
Defaults to |
Value
A list containing the database connection pool (db
) and the table
name (table
), or NULL
if in ignore mode or if there's an error.
Examples
if (interactive()) {
# Assuming SURVEYDOWN_PASSWORD is set in .Renviron
db <- sd_database(
host = "aws-0-us-west-1.pooler.supabase.com",
dbname = "postgres",
port = "6---",
user = "postgres.k----------i",
table = "your-table-name",
ignore = FALSE
)
# Print the structure of the connection
str(db)
# Close the connection pool when done
if (!is.null(db)) {
pool::poolClose(db$db)
}
}
Configure database settings
Description
Set up or modify database configuration settings in a .env file. These settings are used to establish database connections for storing survey responses.
Usage
sd_db_config(
host = NULL,
dbname = NULL,
port = NULL,
user = NULL,
table = NULL,
password = NULL,
interactive = NULL
)
Arguments
host |
Character string. Database host |
dbname |
Character string. Database name |
port |
Character string. Database port |
user |
Character string. Database user |
table |
Character string. Table name |
password |
Character string. Database password |
interactive |
Logical. Whether to use interactive setup. Defaults to TRUE if no parameters provided |
Value
Invisibly returns a list of the current configuration settings
See Also
-
sd_db_connect()
to connect to the database
Examples
if (interactive()) {
# Interactive setup
sd_db_config()
# Update specific settings
sd_db_config(table = "new_table")
# Update multiple settings
sd_db_config(
host = "new_host",
port = "5433",
table = "new_table"
)
}
Connect to database
Description
Establish a connection to the database using settings from .env file. This function creates a connection pool for efficient database access and provides options for local data storage when needed.
Usage
sd_db_connect(env_file = ".env", ignore = FALSE, gssencmode = "auto")
Arguments
env_file |
Character string. Path to the env file. Defaults to ".env" |
ignore |
Logical. If |
gssencmode |
Character string. The GSS encryption mode for the database
connection. Defaults to
|
Value
A list containing the database connection pool (db
) and table name (table
),
or NULL
if ignore is TRUE
or if connection fails
Examples
if (interactive()) {
# Connect using settings from .env
db <- sd_db_connect()
# Use local storage instead of database
db <- sd_db_connect(ignore = TRUE)
# Close connection when done
if (!is.null(db)) {
pool::poolClose(db$db)
}
}
Create a placeholder for a reactive survey question
Description
This function is depreciated - use sd_output()
instead.
Usage
sd_display_question(id)
Arguments
id |
A unique identifier for the question. |
Value
A 'shiny' UI element that serves as a placeholder for the reactive question.
Display the value of a survey question
Description
This function is depreciated - use sd_output()
instead.
Usage
sd_display_value(id, display_type = "inline", wrapper = NULL, ...)
Arguments
id |
The ID of the question to display |
display_type |
The type of display. Can be |
wrapper |
A function to wrap the output |
... |
Additional arguments passed to the wrapper function |
Value
A 'shiny' UI element displaying the question's value
Fetch data from a database table with automatic reactivity detection
Description
This function retrieves all data from a specified table in a database. It automatically detects whether it's being used in a reactive context (e.g., within a 'shiny' application) and behaves accordingly. In a reactive context, it returns a reactive expression that automatically refreshes the data at specified intervals.
Usage
sd_get_data(db, table = NULL, refresh_interval = NULL)
Arguments
db |
A list containing database connection details created using
|
table |
Character string. Database table name to obtain data from,
overrides the table provided in the |
refresh_interval |
Numeric. The time interval (in seconds) between data
refreshes when in a reactive context. Default is |
Value
In a non-reactive context, returns a data frame containing all rows and columns from the specified table. In a reactive context, returns a reactive expression that, when called, returns the most recent data from the specified database table.
Examples
# Non-reactive context example
## Not run:
library(surveydown)
# Assuming you have a database connection called db created using
# sd_database(), you can fetch data with:
data <- sd_get_data(db)
head(data)
# Reactive context example (inside a surveydown app)
server <- function(input, output, session) {
data <- sd_get_data(db, refresh_interval = 10)
output$data_table <- renderTable({
data() # Note the parentheses to retrieve the reactive value
})
}
## End(Not run)
Get URL Parameters in a 'shiny' Application
Description
This function retrieves URL parameters from the current 'shiny' session. It must be called from within a 'shiny' reactive context.
Usage
sd_get_url_pars(...)
Arguments
... |
Optional. Names of specific URL parameters to retrieve. If none are specified, all URL parameters are returned. |
Value
A reactive expression that returns a list of URL parameters.
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_redirect.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
# Reactive expression that generates a url with an id variable
# parsed from the url
url_redirect <- reactive({
params <- sd_get_url_pars()
id <- params["id"]
return(paste0("https://www.google.com?id=", id))
})
# Create the redirect button
sd_redirect(
id = "redirect_url_pars",
url = url_redirect(),
button = TRUE,
label = "Redirect"
)
sd_skip_if(
input$screening_question == "end_1" ~ "end_page_1",
input$screening_question == "end_1" ~ "end_page_2",
)
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Include a folder to the 'shiny' resource path
Description
This function includes a specified folder to the 'shiny' resource path, making it accessible for serving static files in a 'shiny' application. It checks for pre-existing resource paths to avoid conflicts with folders already included by the package.
Usage
sd_include_folder(folder)
Arguments
folder |
A character string specifying the name of the folder to include. This folder should exist in the root directory of your 'shiny' app. |
Value
NULL
invisibly. The function is called for its side effect of
adding a resource path to 'shiny'.
Examples
if (interactive()) {
library(shiny)
# Create an "images" folder
dir.create("images")
# Include the folder in the shiny resource path
sd_include_folder("images")
}
Check if a question is answered
Description
This function checks if a given question has been answered by the user. For matrix questions, it checks if all sub-questions (rows) are answered.
Usage
sd_is_answered(question_id)
Arguments
question_id |
The ID of the question to check. |
Value
A logical value: TRUE
if the question is answered, FALSE
otherwise.
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_is_answered.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
sd_show_if(
# If "apple_text" is answered, show the conditional question
sd_is_answered("apple_text") ~ "other_fruit"
)
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Create a 'Next' Button for Page Navigation
Description
This function creates a 'Next' button for navigating to the specified next page in a Surveydown survey. The button can be activated by clicking or by pressing the Enter key when visible.
Usage
sd_next(next_page = NULL, label = NULL)
Arguments
next_page |
Character string. The ID of the next page to navigate to. This parameter is required. |
label |
Character string. The label of the 'Next' button. Defaults to
|
Details
The function generates a 'shiny' action button that, when clicked or when the Enter key is pressed, sets the input value to the specified next page ID, facilitating page navigation within the Shiny application. The button is styled to appear centered on the page and includes a class for Enter key functionality.
Value
A 'shiny' tagList containing the 'Next' button UI element.
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_next.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Output Function for Displaying reactive objects and values
Description
Output Function for Displaying reactive objects and values
Usage
sd_output(
id,
type = NULL,
width = "100%",
display = "text",
inline = TRUE,
wrapper = NULL,
...
)
Arguments
id |
Character string. A unique identifier for the output element. |
type |
Character string. Specifies the type of output corresponding
with the question |
width |
Character string. The width of the UI element. Defaults to
|
display |
Character string. Specifies the display type for |
inline |
Logical. Whether to render the output inline. Defaults to
|
wrapper |
Function. A function to wrap the output. Only used when
|
... |
Additional arguments passed to the underlying 'shiny' functions or the wrapper function. |
Details
The function behaves differently based on the type
parameter:
If
type
isNULL
, it acts likeshiny::uiOutput()
.If
type
is"question"
, it creates a placeholder for a reactive survey question.If
type
is"value"
, it creates an output to display the value of a survey question, with the display style determined by thedisplay
parameter.
Value
A 'shiny' UI element, the type of which depends on the input parameters.
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_output.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Show a Shiny gadget for entering a page ID
Description
This function displays a Shiny gadget that allows the user to input a page ID. Once submitted, it calls sd_add_page() with the specified ID.
Usage
sd_page_gadget()
Value
The entered page ID (invisibly).
Create a survey question
Description
This function creates various types of survey questions for use in a Surveydown survey.
Usage
sd_question(
id,
type = NULL,
label = NULL,
option = NULL,
cols = "80",
direction = "horizontal",
status = "default",
width = "100%",
height = NULL,
selected = NULL,
label_select = "Choose an option...",
grid = TRUE,
individual = TRUE,
justified = FALSE,
force_edges = TRUE,
placeholder = NULL,
resize = NULL,
row = NULL,
default = NULL,
yml = "questions.yml",
...
)
Arguments
id |
A unique identifier for the question, which will be used as the variable name in the resulting survey data. |
type |
Specifies the type of question. Possible values are |
label |
Character string. The label for the UI element, which can be
formatted with markdown. Defaults to |
option |
Named vector for the |
cols |
Integer. Number of columns for the |
direction |
Character string. The direction for button groups
( |
status |
Character string. The status for button groups.
Defaults to |
width |
Character string. The width of the UI element.
Defaults to |
height |
Character string. The height of the input for the
|
selected |
Value. The selected value(s) for certain input elements. |
label_select |
Character string. The label for the select input.
Defaults to |
grid |
Logical. Whether to show a grid for slider input.
Defaults to |
individual |
Logical. Whether buttons in a group should be individually
styled. Defaults to |
justified |
Logical. Whether buttons in a group should fill the width
of the parent div. Defaults to |
force_edges |
Logical. Whether to force edges for slider input.
Defaults to |
placeholder |
Character string. Placeholder text for |
resize |
Character string. Resize option for textarea input.
Defaults to |
row |
List. Used for |
default |
Numeric, length 1 (for a single sided slider), or 2 for a two sided (range based) slider. Values to be used as the starting default for the slider. Defaults to the median of values. |
yml |
Character string. The name of the YAML file to load question configurations from.
Defaults to |
... |
Additional arguments, often specific to different input types.
Examples include |
Details
The function supports various question types:
-
"select"
: A dropdown selection -
"mc"
: Multiple choice (single selection) -
"mc_multiple"
: Multiple choice (multiple selections allowed) -
"mc_buttons"
: Multiple choice with button-style options (single selection) -
"mc_multiple_buttons"
: Multiple choice with button-style options (multiple selections allowed) -
"text"
: Single-line text question -
"textarea"
: Multi-line text question -
"numeric"
: Numeric question -
"slider"
: Slider question -
"slider_numeric"
: Extended numeric slider question -
"date"
: Date question -
"daterange"
: Date range question -
"matrix"
: Matrix-style question with rows and columns
For "matrix"
type questions, use the row
parameter to define the rows of
the matrix. Each element in the row
list should have a name (used as the
row ID) and a value (used as the row label).
Value
A 'shiny' UI element wrapped in a div with a data attribute for question ID.
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "basic_survey.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Create a Custom Question with a Shiny Widget
Description
This function creates a custom survey question that incorporates any Shiny widget and captures its interaction value. It allows for the integration of interactive visualizations (e.g., maps, plots) or other custom Shiny outputs into a survey, storing the result of user interaction as survey data.
Usage
sd_question_custom(id, label, output, value, height = "400px")
Arguments
id |
Character string. A unique identifier for the question. |
label |
Character string. The label text for the question, which can include HTML formatting. |
output |
Shiny UI element. The output of a Shiny widget (e.g.,
|
value |
Reactive expression that returns the value to be stored in the survey data when the user interacts with the widget. |
height |
Character string. The height of the widget output. Defaults to "400px". |
Details
The function creates a custom question container that includes:
A visible widget output that users can interact with
A hidden text input that stores the value from the interaction
Automatic tracking of user interaction for progress monitoring
The value to be stored is controlled by the reactive expression provided to
the value
parameter, which should update whenever the user interacts with
the widget in the desired way.
Value
None (called for side effects)
See Also
sd_question()
for standard question types
Examples
if (interactive()) {
library(surveydown)
library(leaflet)
server <- function(input, output, session) {
# Create map output
output$usa_map <- renderLeaflet({
leaflet() |>
addTiles() |>
setView(lng = -98.5795, lat = 39.8283, zoom = 4)
})
# Reactive value for selected location
selected_location <- reactiveVal(NULL)
# Click observer
observeEvent(input$usa_map_click, {
click <- input$usa_map_click
if (!is.null(click)) {
selected_location(
sprintf("Lat: %0.2f, Lng: %0.2f", click$lat, click$lng)
)
}
})
# Create the custom question
sd_question_custom(
id = "location",
label = "Click on your location:",
output = leafletOutput("usa_map", height = "400px"),
value = selected_location
)
sd_server()
}
shinyApp(ui = sd_ui(), server = server)
}
Show a Shiny gadget for selecting a question type
Description
This function displays a Shiny gadget that allows the user to select a question type from a dropdown menu. Once submitted, it calls sd_add_question() with the specified type.
Usage
sd_question_gadget(chunk = FALSE)
Arguments
chunk |
Logical. If |
Value
The selected question type (invisibly).
Create a reactive value that is also stored in survey data
Description
This function creates a reactive value similar to Shiny's reactive() function, but also automatically stores the calculated value in the survey data.
Usage
sd_reactive(id, expr, blank_na = TRUE)
Arguments
id |
Character string. The id (name) of the value to be stored in the data. |
expr |
An expression that calculates a value based on inputs |
blank_na |
Logical. If TRUE, NA values are converted to empty strings. Default is TRUE. |
Value
A reactive expression that can be called like a function
Examples
# This example shows how sd_reactive would be used in the app.R file
if (interactive()) {
library(surveydown)
library(shiny)
# Demo app setup
server <- function(input, output, session) {
# Create a reactive value that is stored in survey data
product <- sd_reactive("product", {
as.numeric(input$first_number) * as.numeric(input$second_number)
})
# Display the result
output$result <- renderText({
paste("The product is:", product())
})
# The rest of your survey setup...
sd_server()
}
# In your survey.qmd file, you would use:
# The product is: `r sd_output("product", type = "value")`
}
Create a Redirect Element for 'shiny' Applications
Description
This function creates a UI element that redirects the user to a specified URL. It can be used in both reactive and non-reactive contexts within 'shiny' applications.
Usage
sd_redirect(
id,
url,
button = TRUE,
label = "Click here",
delay = NULL,
newtab = FALSE
)
Arguments
id |
A character string of a unique id to be used to identify the redirect button in the survey body. |
url |
A character string specifying the URL to redirect to. |
button |
A logical value indicating whether to create a button ( |
label |
A character string for the button or text label. Defaults to
|
delay |
An optional numeric value specifying the delay in seconds before
automatic redirection. If |
newtab |
A logical value indicating whether to open the URL in a new
tab ( |
Value
In a reactive context, returns a function that when called, renders the redirect element. In a non-reactive context, returns the redirect element directly.
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_redirect.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
# Reactive expression that generates a url with an id variable
# parsed from the url
url_redirect <- reactive({
params <- sd_get_url_pars()
id <- params["id"]
return(paste0("https://www.google.com?id=", id))
})
# Create the redirect button
sd_redirect(
id = "redirect_url_pars",
url = url_redirect(),
button = TRUE,
label = "Redirect"
)
sd_skip_if(
input$screening_question == "end_1" ~ "end_page_1",
input$screening_question == "end_1" ~ "end_page_2",
)
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Server logic for a surveydown survey
Description
This function defines the server-side logic for a 'shiny' application used in surveydown. It handles various operations such as conditional display, progress tracking, page navigation, database updates for survey responses, and exit survey functionality.
Usage
sd_server(
db = NULL,
required_questions = NULL,
all_questions_required = FALSE,
start_page = NULL,
auto_scroll = FALSE,
rate_survey = FALSE,
language = "en",
use_cookies = TRUE,
highlight_unanswered = TRUE,
highlight_color = "gray"
)
Arguments
db |
A list containing database connection information created using
|
required_questions |
Vector of character strings. The IDs of questions
that must be answered. Defaults to |
all_questions_required |
Logical. If |
start_page |
Character string. The ID of the page to start on.
Defaults to |
auto_scroll |
Logical. Whether to enable auto-scrolling to the next
question after answering. Defaults to |
rate_survey |
Logical. If |
language |
Set the language for the survey system messages. Include
your own in a |
use_cookies |
Logical. If |
highlight_unanswered |
Logical. If |
highlight_color |
Character string. Color for highlighting unanswered questions. Options are "blue", "orange", "green", "purple", "gray", or "grey". Defaults to "gray". |
Details
The function performs the following tasks:
Initializes variables and reactive values.
Implements conditional display logic for questions.
Tracks answered questions and updates the progress bar.
Handles page navigation and skip logic.
Manages required questions.
Performs database operation.
Controls auto-scrolling behavior based on the
auto_scroll
argument.Uses sweetalert for warning messages when required questions are not answered.
Handles the exit survey process based on the
rate_survey
argument.
Value
This function does not return a value; it sets up the server-side logic for the 'shiny' application.
Progress Bar
The progress bar is updated based on the last answered question. It will jump to the percentage corresponding to the last answered question and will never decrease, even if earlier questions are answered later. The progress is calculated as the ratio of the last answered question's index to the total number of questions.
Database Operations
If db
is provided, the function will update the database with survey
responses. If db
is NULL
(ignore mode), responses will be saved to a local
CSV file.
Auto-Scrolling
When auto_scroll
is TRUE
, the survey will automatically scroll to the
next question after the current question is answered. This behavior can be
disabled by setting auto_scroll = FALSE
.
Exit Survey
When rate_survey = TRUE
, the function will show a rating question when
the user attempts to exit the survey. When FALSE
, it will show a simple
confirmation dialog. The rating, if provided, is saved with the survey data.
See Also
sd_database()
, sd_ui()
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "basic_survey.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
# sd_server() accepts these following parameters
sd_server(
db = NULL,
required_questions = NULL,
all_questions_required = FALSE,
start_page = NULL,
auto_scroll = FALSE,
rate_survey = FALSE,
language = "en",
use_cookies = TRUE,
highlight_unanswered = TRUE,
highlight_color = "gray"
)
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Set password for surveydown survey
Description
This function sets your surveydown password, which is used to access
the 'PostgreSQL' data (e.g. Supabase). The password is saved in a .Renviron
file and adds .Renviron
to .gitignore
.
Usage
sd_set_password(password)
Arguments
password |
Character string. The password to be set for the database connection. |
Details
The function performs the following actions:
Creates a
.Renviron
file in the root directory if it doesn't exist.Adds or updates the
SURVEYDOWN_PASSWORD
entry in the.Renviron
file.Adds
.Renviron
to.gitignore
if it's not already there.
Value
None. The function is called for its side effects.
Examples
## Not run:
# Set a temporary password for demonstration
temp_password <- paste0(sample(letters, 10, replace = TRUE), collapse = "")
# Set the password
sd_set_password(temp_password)
# After restarting R, verify the password was set
cat("Password is :", Sys.getenv('SURVEYDOWN_PASSWORD'))
## End(Not run)
Required Set Up Function
Description
This function is depreciated and no longer needed.
Usage
sd_setup()
Details
The function configures the 'shiny' application to use Bootstrap 5 for styling and enables 'shinyjs' for JavaScript functionalities within the application.
Value
This function does not return a value. It is called for its side effects of setting up the 'shiny' application.
Define show conditions for survey questions and pages
Description
This function is used to define conditions under which certain questions or pages in the survey should be shown.
It takes one or more formulas where the left-hand side is the condition and the right-hand side is the target question ID or page ID.
If called with no arguments, it will return NULL
and set no conditions.
Usage
sd_show_if(...)
Arguments
... |
One or more formulas defining show conditions. The left-hand side of each formula should be a condition based on input values, and the right-hand side should be the ID of the question or page to show if the condition is met. |
Value
A list of parsed conditions, where each element contains the condition and the target question or page ID.
Returns NULL
if no conditions are provided.
See Also
sd_skip_forward()
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_show_if.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
sd_show_if(
# If "Other" is chosen, show the conditional question
input$fav_fruit == "other" ~ "fav_fruit_other",
# If condition is met, show specific page
input$category == "advanced" ~ "advanced_page"
)
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Define forward skip conditions for survey pages
Description
This function is used to define conditions under which certain pages in the survey should be skipped ahead to (forward only). It takes one or more formulas where the left-hand side is the condition and the right-hand side is the target page ID.
Usage
sd_skip_forward(...)
Arguments
... |
One or more formulas defining skip conditions. The left-hand side of each formula should be a condition based on input values, and the right-hand side should be the ID of the page to skip to if the condition is met. Only forward skipping (to pages later in the sequence) is allowed. |
Value
A list of parsed conditions, where each element contains the condition and the target page ID.
See Also
sd_show_if()
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_skip_forward.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
# Skip forward to specific pages based on fruit selection
sd_skip_forward(
input$fav_fruit == "apple" ~ "apple_page",
input$fav_fruit == "orange" ~ "orange_page",
input$fav_fruit == "other" ~ "other_page"
)
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Define skip conditions for survey pages (Deprecated)
Description
This function is deprecated. Please use sd_skip_forward()
instead.
This function is used to define conditions under which certain pages in the
survey should be skipped. It now behaves like sd_skip_forward()
where only forward
skipping is allowed to prevent navigation loops.
Usage
sd_skip_if(...)
Arguments
... |
One or more formulas defining skip conditions. The left-hand side of each formula should be a condition based on input values, and the right-hand side should be the ID of the page to skip to if the condition is met. |
Value
A list of parsed conditions, where each element contains the condition and the target page ID.
Store a value in the survey data
Description
This function allows storing additional values to be included in the survey data, such as respondent IDs or other metadata.
Usage
sd_store_value(value, id = NULL)
Arguments
value |
The value to be stored. This can be any R object that can be coerced to a character string. |
id |
(Optional) Character string. The id (name) of the value in the
data. If not provided, the name of the |
Value
NULL
(invisibly)
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_ui.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "basic_survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
# Create a respondent ID to store
respondentID <- 42
# Store the respondentID
sd_store_value(respondentID)
# Store the respondentID as the variable "respID"
sd_store_value(respondentID, "respID")
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Create the UI for a surveydown survey
Description
This function creates the user interface for a surveydown survey, including necessary CSS and JavaScript files, and applies custom styling. It retrieves theme and progress bar settings from the survey.qmd file.
Usage
sd_ui()
Details
The function reads the following settings from the survey.qmd YAML header:
-
theme
: The theme to be applied to the survey. -
barcolor
: The color of the progress bar (should be a valid hex color). -
barposition
: The position of the progress bar ('top'
,'bottom'
, or'none'
).
If barcolor
is not specified or is NULL
, the default theme color will be
used. If barposition
is not specified, it defaults to 'top'.
Value
A 'shiny' UI object
See Also
sd_server()
for creating the server-side logic of the survey
Examples
if (interactive()) {
library(surveydown)
# Get path to example survey file
survey_path <- system.file("examples", "sd_ui.qmd",
package = "surveydown")
# Copy to a temporary directory
temp_dir <- tempdir()
file.copy(survey_path, file.path(temp_dir, "survey.qmd"))
orig_dir <- getwd()
setwd(temp_dir)
# Define a minimal server
server <- function(input, output, session) {
sd_server()
}
# Run the app
shiny::shinyApp(ui = sd_ui(), server = server)
# Clean up
setwd(orig_dir)
}
Check Surveydown Version
Description
This function checks if the local surveydown package is up-to-date with the latest online version. It compares the local version with the latest version available on GitHub and provides information about whether an update is needed.
Usage
sd_version()
Value
No return value, called for side effects (prints version information and update status to the console).
Examples
surveydown::sd_version()