Skip to contents

Each page corresponds to a page within the app/questionnaire.

Usage

new_page(
  page_id,
  render,
  condition = NULL,
  run_before = NULL,
  render_before = NULL,
  render_after = NULL,
  run_after = NULL
)

Arguments

page_id

A unique string identifiying this page. (Required) This will be used to store data.

render

Function to render the page. (Required) It is expected, that the function returns a list of shiny tags. Its output will be combined with render_before and render_after. This function has access to the shiny session and the run_before_output.

condition

Function to check whether the page should be shown. When this function returns TRUE, the page will be shown upon navigating there, if it returns FALSE it will be skipped. Defaults to show the page. This function has access to the shiny session.

run_before

Function that prepares data to render the page. Called immediately after condition (if condition returned TRUE). Whatever run_before returns is available in render, render_before and render_after as run_before_output. This function has access to the shiny session.

render_before

Called exactly like render. Output will be added just before the output from render. Mainly used to add additional outputs to existing pages.

render_after

Called exactly like render. Output will be added just after the output from render. Mainly used to add additional outputs to existing pages.

run_after

Function that handles the user input when they leave the page. This function has access to the shiny session and shiny input.

Value

A new page object.

Details

Pages are rendered by calling the different life-cycle functions one after another. The order in which they are called is as follows:

  1. condition (session) Only if this evaluated to TRUE, continue.

  2. run_before (session)

  3. render_before (session, run_before_output, input, output)

  4. render (session, run_before_output, input, output)

  5. render_after (session, run_before_output, input, output) The outputs from render_before, render & render_after are stitched together to produce the final HTML output of the page.

  6. run_after (session, input, output) Run when the user leaves the page (=clicks the next button). Any user input has to be handled here. For each question asked, one will typically call set_item_data() to save the collected data internally.

Each of the life-cycle functions above is annotated with the paramaters it has access to. session, input and output are passed directly from shiny and correspond to the objects made available by shiny::shinyServer(), run_before_output is available for convenience and corresponds to whatever is returned by run_before.

Some side-effects occur:

  • occupationMeasurement:::init_page_data is called before 1. run_before. It sets up an internal representation of the page data to be saved.

  • occupationMeasurement:::finalize_data is called before 6. run_before.

  • occupationMeasurement:::save_page_data is called after 6. run_before. It saves the responses on a hard drive, i.e. it appends the responses from this page to table_name == "answers". See the vignette and create_app_settings() for details.

Use of render_before, render_after is discouraged if not necessary, as these two life-cycle functions have only been added to allow for easier modification and extension of existing pages.

Examples

data.table::setDTthreads(1)

if (FALSE) {
very_simple_page <- new_page(
  page_id = "example",
  render = function(session, run_before_output, input, output, ...) {
    list(
      shiny::tags$h1("My test page"),
      button_previous(),
      button_next()
    )
  }
)

# Example where we also save some data
page_that_saves_two_items <- new_page(
  page_id = "questions_1_and_2",
  render = function(session, run_before_output, page, input, output, ...) {
    list(
      shiny::tags$h1("Questions"),
      shiny::textAreaInput(
        inputId = "day_freetext",
        label = "How was your day? Please give a detailed answer.",
        value = get_item_data(
          session = session, page_id = page$page_id,
          item_id = "day_freetext",
          key = "response_text"
        )
      ),
      shiny::tags$p("How would you rate your day? On a scale of 1 - 4"),
      radioButtons(
        inputId = "day_radio",
        label = NULL,
        width = "100%",
        choices = list(One = 1, Two = 2, Three = 3, Four = 4),
        selected = get_item_data(
          session = session,
          page_id = page$page_id,
          item_id = "day_radio",
          key = "response_id",
          default = character(0)
        )
      ),
      button_previous(),
      button_next()
    )
  },
  run_after = function(session, page, input, ...) {
    set_item_data(
      session = session,
      page_id = page$page_id,
      item_id = "day_freetext",
      response_text = input$day_freetext
    )
    set_item_data(
      session = session,
      page_id = page$page_id,
      item_id = "day_radio",
      response_id = input$day_radio
    )
  }
)

questionnaire_that_saves_two_items <- list(
  page_that_saves_two_items,
  # So we have a next page to go to
  very_simple_page
)

if (interactive()) {
  app(questionnaire = questionnaire_that_saves_two_items)
}
}