Extending shinysurveys with Custom Input Types

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(shinysurveys)
library(tibble)

Note: This is a pared down version of an article originally posted on my personal blog. I plan to update documentation there more regularly than in the vignettes.

Motivation

The original idea for {shinysurveys} was to provide a select set of well-supported input types that are commonly used with surveys. However, shortly after the package was published on CRAN, additional input types were requested (see GitHub issue #6 or #18).

In order to make the package as light-weight as possible (minimize dependence on external code), I did not wish to implement any input types not native to {shiny}. I also did not want to rewrite the internals of {shinysurveys} whenever a new input-type was requested. As a solution, I developed a framework for custom inputs to allow users to include different input types that meet their use case. In the next section, I outline two examples of how to add custom input types.

Examples

Adding a sliderInput

Consider the question "On a scale from 1-10, how much do you love sushi?". An ideal input type would be {shiny}'s sliderInput. However, this is not natively supported by {shinysurveys} as the slider input requires multiple arguments, including a minimum, maximum, and starting value. To get around this, we can define a new input type using a new function extendInputType(). As in a typical shiny survey, we can define our question as follows:

# Define a question as normal with the `input_type` set to "slider", which is not natively supported by {shinysurveys}.

slider_question <- data.frame(
  question = "On a scale from 1-10, how much do you love sushi?",
  option = NA,
  input_type = "slider",
  input_id = "sushi_scale",
  dependence = NA,
  dependence_value = NA,
  required = TRUE
  )

This looks like:

slider_question

If we try to define the user-interface component of the shiny application, we will get the following error which most commonly occurs when {shinysurveys} doesn't recognize an input type.

library(shiny)
library(shinysurveys)

ui <- fluidPage(
  surveyOutput(df = slider_question,
               survey_title = "Testing the Slider Input")
)

To overcome this, we can use extendInputType(). This function accepts two arguments. The first, input_type, is a string of the input type used in the questions data frame. The second is the input definition. Consider:

# Register a slider input to {shinysurveys} with a custom minimum and maximum value.

extendInputType(input_type = "slider", {
  shiny::sliderInput(
    inputId = surveyID(),
    label = surveyLabel(),
    min = 1,
    max = 10,
    value = 5
    ) 
})

Note the inputId and label are set to surveyID() and surveyLabel(), respectively. These are necessary helper functions to ensure that survey features such as required questions function properly. As such, all extensions need inputId = surveyID() and label = surveyLabel().

Now, when we try to define the user-interface, we don't see any errors:

# By defining the input type above, this works! Yay!
ui <- fluidPage(
  surveyOutput(df = slider_question,
               survey_title = "Testing the Slider Input")
)

When running the full application, we see the following survey:

Adding a dateInput

As requested in issue #18, a user needed a dateInput with special restrictions for possible values (dates). The user's reprex showed the error we saw earlier, because {shinysurveys} does not natively support "date" inputs. Consider again the following question:

# Define a question as normal with the `input_type` set to "date", which is not natively supported by {shinysurveys}.
date_question <- data.frame(
  question = "When do you graduate?",
  option = NA,
  input_type = "date",
  input_id = "grad_date",
  dependence = NA,
  dependence_value = NA,
  required = FALSE
  )

This looks like:

date_question

As in the slider example, if we try to define the user-interface component of the shiny application, we will get the following error which most commonly occurs when {shinysurveys} doesn't recognize an input type.

library(shiny)
library(shinysurveys)

ui <- fluidPage(
  surveyOutput(df = date_question,
               survey_title = "Testing the Date Input")
)

Using extendInputType() we can overcome this.

# Register a date input to {shinysurveys}, limiting possible dates to a twenty-day period.

extendInputType("date", {
  shiny::dateInput(
    inputId = surveyID(),
    value = Sys.Date(),
    label = surveyLabel(),
    min = Sys.Date()-10,
    max = Sys.Date()+10
  )
})

Now, when we try to define the user-interface, we don't see any errors:

# By defining the input type above, this works! Yay!
ui <- fluidPage(
  surveyOutput(df = date_question,
               survey_title = "Testing the Date Input")
)

When running the full application, we see the following survey:



Try the shinysurveys package in your browser

Any scripts or data that you put into this service are public.

shinysurveys documentation built on July 11, 2021, 9:06 a.m.