Survey Components
This guide covers the main elements in your .qmd
survey file as well as how to add content to your survey, like pages, questions, etc.
Overview
Every surveydown survey is configured in a single .qmd
file that consists of 4 parts:
- The YAML header.
- The setup code chunk.
- The survey body.
- The server code chunk.
1. YAML Header
The YAML header is at the top of the .qmd
file. In addition to two required elements, the YAML can be used to set the survey theme as well as modify the survey progress bar.
Required content
For a surveydown survey, your YAML must contain at least the following:
---
server: shiny
filters: [surveydown]
---
The server: shiny
part ensures that the document will render as a Shiny app. The filters: [surveydown]
part applies the surveydown Quarto extension to the project, which is required.
Setting the theme
The YAML can also be used to set several optional global settings, such as the overall survey theme
:
---
theme: united # Any bootswatch theme
---
There are 25 bootswatch themes to choose from. You can also provide a custom.scss
file to further modify the theme, or even combine the two, e.g.:
---
theme: [united, custom.scss]
---
Progress bar
You can modify the survey progress bar with the barcolor
and barposition
keys, e.g.:
---
barcolor: theme
barposition: top
---
The barcolor
key defines the color of the progress bar. It defaults to theme
, meaning it will take the primary theme color. You may also use any hex code to overwrite this color as you wish, e.g.: #768692
.
The barposition
key defines the position of the progress bar. It defaults to top
, but can also be changed to bottom
or none
(to remove the bar). The progress bar updates on every question the user clicks on, not pages.
2. Setup code chunk
After the YAML header, you’ll need to load the surveydown
package and run the sd_setup()
function. This should be placed inside a code chunk that looks like this:
```{r}
#| context: setup
#| warning: false
#| message: false
# Load the package
library(surveydown)
# Run initial setup function (essential - do not delete)
sd_setup()
# Setup your database
db <- sd_database(
host = "",
dbname = "",
port = "",
user = "",
table = "",
ignore = TRUE
)
```
Anything loaded in the setup chunk is accessible in both your survey body and your server. This is similar in a standard Shiny app to anything loaded in the global environment before defining a ui
and server
.
Note: Every surveydown survey requires loading the surveydown
package with library(surveydown)
and running the sd_setup()
function.
We also define a db
object that will be used to store survey data. You can find more on how to set this up on the Store Data page.
3. Survey body
The survey body is all the content in between your setup code chunk and your server code chunk. You can use markdown (or the RStudio visual editor) to insert text, images, etc. just like you would in any Quarto document.
The unique elements to a surveydown survey are pages, navigation buttons, and questions.
Adding pages
In surveydown, pages are defined using fences (:::
), like this:
::: {#welcome .sd-page}
1 content here
Page
:::
::: {#page2 .sd-page}
2 content here
Page
:::
As you can see, we use three colon symbols :::
, called a “fence”, to mark the start and end of pages. This notation is commonly used in Quarto for a variety of use cases, like defining subfigures in images.
In the starting fence, you need to define a page name (e.g. welcome
and page2
in the example above) and you need to define the class as .sd-page
. Then anything you put between the page fences will appear on that page.
Ending the survey
To end a survey, all you have to do is create a page with no sd_next()
button on it. This will effectively serve as a ending page, because the respondent will not be able to navigate anywhere else once reaching a page with no sd_next()
button.
For example, you may want to have a screen-out page that respondents are sent to if they answer a certain way on a question (see the basic skipping page for an example). You can do this by creating a page with no sd_next()
button on it, like this:
::: {#screenout .sd-page}
Screenout page content here
:::
When a respondent reaches this page, they will not be able to navigate anywhere else, so the survey is over.
Adding questions
Every survey question is created using the sd_question()
function inside a code chunk. The question type is defined by the type
argument. For example, to add a multiple choice question, you could insert the following code chunk:
```{r}
sd_question(
type = 'mc',
id = 'penguins',
label = "Which is your favorite type of penguin?",
option = c(
'Adélie' = 'adelie',
'Chinstrap' = 'chinstrap',
'Gentoo' = 'gentoo'
)
)
```
The above code chunk will create a multiple choice question that looks like this:
The sd_question()
function can be used to create a variety of question types, like text input, select drop down choices, and more by changing the type
argument (see the Questions Types page).
The function has many other arguments for customizing the look and feel of the question, such as the height
and width
(see the Formatting Questions page).
By default all questions are optional, but you can make questions required in the configuration options (see the Configuration Options page for details).
4. Server code chunk
At the very bottom of the .qmd file is a special “server” code chunk (that’s the #| context: server
bit) that defines the app server. This is where you can set custom control logic and other configuration options. It looks like this:
```{r}
#| context: server
# Define the configuration settings
config <- sd_config()
# The sd_server() function initiates your survey - don't change this
sd_server(
input = input,
session = session,
config = config,
db = db
)
```
The sd_config()
function is where you can define configuration options for the survey, such as conditional display (conditionally displaying a question based on responses to questions), or conditional skip (conditionally sending the respondent to a page based on responses to questions). See the Configuration Options page for details.
The sd_server()
function at the bottom makes everything run, which you can safely ignore - just don’t change it and all will be good! It should always be the last code in the server code chunk.