Configuration Options

All survey configuration settings are defined within the server function in the app.R file. The server() function is a standard Shiny server function that takes input, output, and session as arguments.

If you create a new survey using a template, the server() function looks like this:

server <- function(input, output, session) {

  sd_skip_if()

  sd_show_if()

  sd_server(db = db)

}

The sd_skip_if() and sd_show_if() functions are used to define conditional skip and show logic for the survey, and the sd_server() function is used to run the survey. The db = db argument is required if you are using a database connection, which should be defined using the sd_database() function (we typically store it as db in the global environment…see the Store Data page for more details).

This page goes over how to use each of these functions to control many aspects of the survey flow logic.

Conditional display

It is often useful to have a question display based on some condition, such as the respondent choosing a particular value in a multiple choice question.

For example, let’s say we have a choice question about people’s favorite penguin type, and the last option is “other”. If the respondent chose it, you may want a second question to display that allows them to specify the “other” penguin type, like this:


To implement this, you first need to define both the conditional question and the target question in the survey.qmd file, like this:

```{r}
# Conditional question
sd_question(
  type  = "mc",
  id    = "penguins",
  label = "Which is your favorite type of penguin?",
  option = c(
    "Adélie"    = "adelie",
    "Chinstrap" = "chinstrap",
    "Gentoo"    = "gentoo",
    "Other"     = "other"
  )
)

# Target question
sd_question(
  type  = "text",
  id    = "penguins_other", 
  label = "Please specify the other penguin type:"
)
```
1
The "penguins" question is the conditional question, and the "penguins_other" question is the target question.

Then in the server function in the app.R file, you can use the sd_show_if() function to define that the "penguins_other" question would only be shown if the respondent chose the "other" option in the "penguins" question, like this:

server <- function(input, output, session) {

  sd_show_if(
    input$penguins == "other" ~ "penguins_other"
  )

  sd_server(db = db)

}
1
input$penguins == "other" is the condition, and "penguins_other" is the target question that will be shown if the condition is met.

You can provide multiple conditions to the sd_show_if() function, each separated by a comma. The structure for each condition in the sd_show_if() function is always:

<condition> ~ "target_question_id"

In the example above, the input$penguins == "other" is the condition, and "penguins_other" is the target question. The ~ symbol is used to separate the condition from the target question.

Note

The input object is a Shiny object that stores each question id defined by sd_question() in your survey.qmd file, so whenever referring to a question in a condition, you must use the format input$question_id.

For situlations where the conditional logic is more complex, we recommend defining a custom function that will return a logical value (TRUE or FALSE) indicating whether the target question should be displayed. You can then pass this function to the sd_show_if() function. Using the same example as above, you might have something like this:

server <- function(input, output, session) {

  complex_condition <- function(input) {
    # Condition code here, e.g. check the values of multiple questions
    # Must return a logical value (TRUE or FALSE)
  }

  sd_show_if(
    complex_condition ~ "penguins_other"
  )

  sd_server(db = db)

}
1
Note that here the complex_condition function is defined as the condition without () after it. This is because we are passing the function itself, not the result of the function.

Conditional skipping

Often times you’ll want to send respondents to different parts of the survey based on some condition, such as the respondent choosing a particular value in a multiple choice question.

For example, let’s say you want to screen out people who do not own a vehicle. To do this, you would first define a question in your survey.qmd file about their vehicle ownership, e.g.:

```{r}
sd_question(
  type  = 'mc',
  id    = 'vehicle_ownership',
  label = "Do you own your vehicle?",
  option = c(
    'Yes' = 'yes',
    'No'  = 'no'
  )
)
```

You would also need to define a screenout page to send respondents to, like this:

::: {#screenout .sd-page}

Sorry, but you are not qualified to take our survey.

:::

Then in the server function in the app.R file, you can use the sd_skip_if() function to define the condition under which the respondent will be sent to the target screenout page, like this:

server <- function(input, output, session) {

  sd_skip_if(
    input$vehicle_ownership == "no" ~ "screenout"
  )

  sd_server(db = db)

}
1
input$vehicle_ownership == "no" is the condition, and "screenout" is the target page that the respondent will be sent to if the condition is met.

Just like the sd_show_if() function, you can provide multiple conditions to the sd_skip_if() function, each separated by a comma. The structure for each condition in the sd_skip_if() function is always:

<condition> ~ "target_page_id"

For more complex conditional skipping logic you could define a custom function that returns a logical value (TRUE or FALSE) indicating whether a condition has been met, then pass this function to the sd_skip_if() function. Using the same example as above, you might have something like this:

server <- function(input, output, session) {

  complex_condition <- function(input) {
    # Condition code here, e.g. check the values of multiple questions
    # Must return a logical value (TRUE or FALSE)
  }

  sd_skip_if(
    complex_condition ~ "screenout"
  )

  sd_server(db = db)

}
1
Note that here the complex_condition function is defined as the condition without () after it. This is because we are passing the function itself, not the result of the function.

Server options

The sd_server() function called inside the server() function in the app.R file has several other arguments that you can use to customize the survey behavior.

Required questions

By default, no questions are required. However, you can make questions required by providing a vector containing the id of the questions to be required to the required_questions argument in sd_server(), like

sd_server(
  required_questions = c("vehicle_ownership", "penguins_other")
)
1
The required_questions argument takes a vector of question ids that you want to make required.

This will make the respondent unable to proceed until they have answered the required questions. It will also place a red asterisk (*) next to the question label to indicate that the question is required.

You can also make all questions required by setting all_questions_required = TRUE like this:

sd_server(
  all_questions_required = TRUE
)

Starting page

When editing your survey, it can be helpful to start the survey at a specific page. You can define the starting page with the start_page argument in the sd_server() function, like this:

sd_server(
  start_page = "page_id"
)

Pre-rendering your survey

When you run your app, the survey.qmd file gets rendered and parsed. We designed it this way to ensure that the latest changes to your survey.qmd file are always included, but this also can result is a delay when the app loads.

To speed this up, you can render your survey.qmd file first, either by clicking the “Render” button in RStudio or by running the following in the terminal:

quarto render survey.qmd

This will generate a survey.html file in the project folder, and you can tell surveydown to use this pre-rendered file by setting the use_html argument to TRUE in the sd_server() function, like this:

sd_server(
  use_html = TRUE
)

This can significantly speed up the initial page loading.

Admin page

Important

The admin page is currently under development and has limited functionality.

By default, the admin page is not created. But if you want one, set admin_page to TRUE inside the sd_server() function, like this:

sd_server(
  admin_page = TRUE
)

When the admin page is enabled, you will be able to access the page by adding ?admin to the end of the survey URL, e.g. https://myname.shinyapps.io/?admin. This will display a login page with a single “Password” parameter, which is the password set using sd_set_password(). See the Password page for details.

The admin page has the following features:

  • Pause Survey: Once clicked, the Shiny app pauses all instances replacing questions with a placeholder page.
  • Pause DB: Once clicked, the all database uploads will be paused. You can still take the survey, but the data will not be updated in the database.
  • Download Data: Download the most recent table instance from the database as a .csv file.
  • Admin Logout and Return to Survey: Once clicked, the admin page will be logged out and the survey will be returned to the start page.
  • Survey Data Preview: View the latest instance of the database table.
Back to top