Title: | Markdown-Based Surveys Using 'Quarto' and 'shiny' |
---|---|
Description: | Generate 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. |
Authors: | John Paul Helveston [aut, cre, cph] , Pingfan Hu [aut, cph] , Bogdan Bunea [aut, cph] , Stefan Munnes [ctb] |
Maintainer: | John Paul Helveston <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.4.2 |
Built: | 2024-11-22 15:30:35 UTC |
Source: | https://github.com/surveydown-dev/surveydown |
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.
sd_add_page()
sd_add_page()
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 a placeholder page ID
A placeholder for the page title
A placeholder for page contents
An R code chunk with a placeholder for questions and a next button
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.
if (interactive()) { library(surveydown) # Insert a new page template sd_add_page() }
if (interactive()) { library(surveydown) # Insert a new page template sd_add_page() }
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.
sd_add_question(type = "mc", chunk = FALSE)
sd_add_question(type = "mc", chunk = FALSE)
type |
A character string specifying the type of question template to
insert.
Default is
|
chunk |
Logical. If |
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.
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.
if (interactive()) { library(surveydown) # Insert a default multiple choice question template sd_add_question() # Insert a text input question template sd_add_question("text") # Insert a slider question template sd_add_question("slider") }
if (interactive()) { library(surveydown) # Insert a default multiple choice question template sd_add_question() # Insert a text input question template sd_add_question("text") # Insert a slider question template sd_add_question("slider") }
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.
sd_close(label = "Exit Survey")
sd_close(label = "Exit Survey")
label |
Character string. The label of the 'Close' button. Defaults to "Exit Survey". |
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.
A 'shiny' tagList containing the 'Close' button UI element and associated JavaScript for the exit process.
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.
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) }
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) }
This function generates a random completion code with a specified number of digits. The code is returned as a character string.
sd_completion_code(digits = 6)
sd_completion_code(digits = 6)
digits |
An integer specifying the number of digits in the completion code. Must be a positive integer. Default is 6. |
A character string representing the random completion code.
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
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
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()
.
sd_copy_value(id, id_copy)
sd_copy_value(id, id_copy)
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 |
NULL
invisibly. This function is called for its side effects.
sd_output()
for displaying the copied value
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) }
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) }
This function creates a new survey template by copying files from the package's template directory to a specified path. It handles file conflicts and provides appropriate warnings and feedback.
sd_create_survey(path = getwd(), structure = "single")
sd_create_survey(path = getwd(), structure = "single")
path |
A character string specifying the directory where the survey template should be created. Defaults to the current working directory. |
structure |
A character string specifying the template structure to use.
Must be either |
The function performs the following steps:
If the specified path is the current working directory, it asks for user confirmation.
Validates the specified structure ("single"
or "multi"
).
Creates the target directory if it doesn't exist.
Copies all files from the package's template directory (based on the specified structure) to the target path.
Preserves the directory structure of the template.
Skips existing files and provides warnings for each skipped file.
Handles .Rproj files specially, skipping if any .Rproj file already exists in the target directory.
Provides feedback on whether files were copied or if all files already existed.
Invisible NULL
. The function is called for its side effects of
creating files and providing user feedback.
if (interactive()) { # Create a single-page survey template sd_create_survey(structure = "single") # Create a multi-page survey template sd_create_survey(structure = "multi") }
if (interactive()) { # Create a single-page survey template sd_create_survey(structure = "single") # Create a multi-page survey template sd_create_survey(structure = "multi") }
This function creates a template translations.yml file in the project root directory that users can customize to modify system messages.
sd_create_translations(language = "en", path = getwd())
sd_create_translations(language = "en", path = getwd())
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. |
Invisible NULL
.
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") }
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") }
This function establishes a connection pool to a 'PostgreSQL' database (e.g. Supabase) and sets up automatic cleanup when the 'shiny' session ends.
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 )
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 )
host |
Character string. The host address of the Supabase database. |
dbname |
Character string. The name of the Supabase database. |
port |
Integer. The port number for the Supabase database connection. |
user |
Character string. The username for the Supabase database connection. |
table |
Character string. The name of the table to interact with in the Supabase database. |
password |
Character string. The password for the Supabase 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 |
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.
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) } }
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) } }
This function is depreciated - use sd_output()
instead.
sd_display_question(id)
sd_display_question(id)
id |
A unique identifier for the question. |
A 'shiny' UI element that serves as a placeholder for the reactive question.
This function is depreciated - use sd_output()
instead.
sd_display_value(id, display_type = "inline", wrapper = NULL, ...)
sd_display_value(id, display_type = "inline", wrapper = NULL, ...)
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 |
A 'shiny' UI element displaying the question's value
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.
sd_get_data(db, refresh_interval = NULL)
sd_get_data(db, refresh_interval = NULL)
db |
A list containing database connection details created using
|
refresh_interval |
Numeric. The time interval (in seconds) between data
refreshes when in a reactive context. Default is |
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.
# 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)
# 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)
This function retrieves URL parameters from the current 'shiny' session. It must be called from within a 'shiny' reactive context.
sd_get_url_pars(...)
sd_get_url_pars(...)
... |
Optional. Names of specific URL parameters to retrieve. If none are specified, all URL parameters are returned. |
A reactive expression that returns a list of URL parameters.
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) }
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) }
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.
sd_include_folder(folder)
sd_include_folder(folder)
folder |
A character string specifying the name of the folder to include. This folder should exist in the root directory of your 'shiny' app. |
NULL
invisibly. The function is called for its side effect of
adding a resource path to 'shiny'.
if (interactive()) { library(shiny) # Create an "images" folder dir.create("images") # Include the folder in the shiny resource path sd_include_folder("images") }
if (interactive()) { library(shiny) # Create an "images" folder dir.create("images") # Include the folder in the shiny resource path sd_include_folder("images") }
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.
sd_is_answered(question_id)
sd_is_answered(question_id)
question_id |
The ID of the question to check. |
A logical value: TRUE
if the question is answered, FALSE
otherwise.
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) }
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) }
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.
sd_next(next_page = NULL, label = "Next")
sd_next(next_page = NULL, label = "Next")
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 "Next". |
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.
A 'shiny' tagList containing the 'Next' button UI element.
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) }
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
sd_output( id, type = NULL, width = "100%", display = "text", inline = TRUE, wrapper = NULL, ... )
sd_output( id, type = NULL, width = "100%", display = "text", inline = TRUE, wrapper = NULL, ... )
id |
Character string. A unique identifier for the output element. |
type |
Character string. Specifies the type of output. Can be
|
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. |
The function behaves differently based on the type
parameter:
If type
is NULL
, it acts like shiny::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 the display
parameter.
A 'shiny' UI element, the type of which depends on the input parameters.
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) }
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) }
This function creates various types of survey questions for use in a Surveydown survey.
sd_question( type, id, label, cols = "80", direction = "horizontal", status = "default", width = "100%", height = "100px", selected = NULL, label_select = "Choose an option...", grid = TRUE, individual = TRUE, justified = FALSE, force_edges = TRUE, option = NULL, placeholder = NULL, resize = NULL, row = NULL )
sd_question( type, id, label, cols = "80", direction = "horizontal", status = "default", width = "100%", height = "100px", selected = NULL, label_select = "Choose an option...", grid = TRUE, individual = TRUE, justified = FALSE, force_edges = TRUE, option = NULL, placeholder = NULL, resize = NULL, row = NULL )
type |
Specifies the type of question. Possible values are "select", "mc", "mc_multiple", "mc_buttons", "mc_multiple_buttons", "text", "textarea", "numeric", "slider", "date", "daterange", and "matrix". |
id |
A unique identifier for the question, which will be used as the variable name in the resulting survey data. |
label |
Character string. The label for the UI element, which can be formatted with markdown. |
cols |
Integer. Number of columns for the textarea input. Defaults to 80. |
direction |
Character string. The direction for button groups ("horizontal" or "vertical"). Defaults to "horizontal". |
status |
Character string. The status for button groups. Defaults to "default". |
width |
Character string. The width of the UI element. Defaults to "100%". |
height |
Character string. The height of the textarea input. Defaults to "100px". |
selected |
Value. The selected value(s) for certain input elements. |
label_select |
Character string. The label for the select input. Defaults to "Choose an option...". |
grid |
Logical. Whether to show a grid for slider input. Defaults to TRUE. |
individual |
Logical. Whether buttons in a group should be individually styled. Defaults to TRUE. |
justified |
Logical. Whether buttons in a group should fill the width of the parent div. Defaults to FALSE. |
force_edges |
Logical. Whether to force edges for slider input. Defaults to TRUE. |
option |
List. Options for the select, radio, checkbox, and slider inputs. |
placeholder |
Character string. Placeholder text for text and textarea inputs. |
resize |
Character string. Resize option for textarea input. Defaults to NULL. |
row |
List. Used for "matrix" type questions. Contains the row labels and their corresponding IDs. |
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 input
"textarea": Multi-line text input
"numeric": Numeric input
"slider": Slider input
"date": Date input
"daterange": Date range input
"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).
A 'shiny' UI element wrapped in a div with a data attribute for question ID.
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) }
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) }
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.
sd_redirect( id, url, button = TRUE, label = "Click here", delay = NULL, newtab = FALSE )
sd_redirect( id, url, button = TRUE, label = "Click here", delay = NULL, newtab = FALSE )
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. Default is "Click here". |
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 ( |
In a reactive context, returns a function that when called, renders the redirect element. In a non-reactive context, returns the redirect element directly.
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) }
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) }
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.
sd_server( db = NULL, required_questions = NULL, all_questions_required = FALSE, start_page = NULL, admin_page = FALSE, auto_scroll = FALSE, rate_survey = FALSE, language = "en" )
sd_server( db = NULL, required_questions = NULL, all_questions_required = FALSE, start_page = NULL, admin_page = FALSE, auto_scroll = FALSE, rate_survey = FALSE, language = "en" )
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 |
admin_page |
Logical. Whether to include an admin page for viewing and
downloading survey data. 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 |
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.
Sets up admin functionality if enabled with the admin_page
argument.
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.
This function does not return a value; it sets up the server-side logic for the 'shiny' application.
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.
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.
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
.
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.
sd_database()
, sd_ui()
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, admin_page = FALSE, auto_scroll = FALSE, rate_survey = FALSE, language = "en" ) } # Run the app shiny::shinyApp(ui = sd_ui(), server = server) # Clean up setwd(orig_dir) }
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, admin_page = FALSE, auto_scroll = FALSE, rate_survey = FALSE, language = "en" ) } # Run the app shiny::shinyApp(ui = sd_ui(), server = server) # Clean up setwd(orig_dir) }
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
.
sd_set_password(password)
sd_set_password(password)
password |
Character string. The password to be set for the database connection. |
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.
None. The function is called for its side effects.
## 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)
## 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)
This function is depreciated and no longer needed.
sd_setup()
sd_setup()
The function configures the 'shiny' application to use Bootstrap 5 for styling and enables 'shinyjs' for JavaScript functionalities within the application.
This function does not return a value. It is called for its side effects of setting up the 'shiny' application.
This function is used to define conditions under which certain questions 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.
If called with no arguments, it will return NULL
and set no conditions.
sd_show_if(...)
sd_show_if(...)
... |
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 to show if the condition is met. |
A list of parsed conditions, where each element contains the condition and the target question ID.
Returns NULL
if no conditions are provided.
sd_skip_if()
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" ) sd_server() } # Run the app shiny::shinyApp(ui = sd_ui(), server = server) # Clean up setwd(orig_dir) }
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" ) sd_server() } # Run the app shiny::shinyApp(ui = sd_ui(), server = server) # Clean up setwd(orig_dir) }
This function displays the password saved in the .Renviron
file under the
SURVEYDOWN_PASSWORD
variable. It includes a confirmation step to ensure
the user wants to display the password in the console. If no password is
found, it suggests using the sd_set_password()
function to define a
password.
sd_show_password()
sd_show_password()
A character string containing the password if found and confirmed, or a message if no password is saved along with a suggestion to set one.
## Not run: surveydown::sd_show_password() ## End(Not run)
## Not run: surveydown::sd_show_password() ## End(Not run)
This function is used to define conditions under which certain pages in the survey should be skipped. It takes one or more formulas where the left-hand side is the condition and the right-hand side is the target page ID.
sd_skip_if(...)
sd_skip_if(...)
... |
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. |
A list of parsed conditions, where each element contains the condition and the target page ID.
sd_show_if()
if (interactive()) { library(surveydown) # Get path to example survey file survey_path <- system.file("examples", "sd_skip_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) { # Skip to page based on input sd_skip_if( 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) }
if (interactive()) { library(surveydown) # Get path to example survey file survey_path <- system.file("examples", "sd_skip_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) { # Skip to page based on input sd_skip_if( 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) }
This function allows storing additional values to be included in the survey data, such as respondent IDs or other metadata.
sd_store_value(value, id = NULL)
sd_store_value(value, id = NULL)
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 |
NULL
(invisibly)
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) }
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) }
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.
sd_ui()
sd_ui()
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'.
A 'shiny' UI object
sd_server()
for creating the server-side logic of the survey
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) }
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) }
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.
sd_version()
sd_version()
No return value, called for side effects (prints version information and update status to the console).
surveydown::sd_version()
surveydown::sd_version()