Skip to contents

When you have created multiple questionnaires with help of the shiny.quetzio already, you may wish to present them to the user sequentially - after the completion of one it may be handy to handle another.

It can be done through the usage of conditionalPanel or by using the toggle_UI method of Quetzio. It can unfortunately cause a lot of unpredicted effects in the end, with a need for more complex logic for you to implement.

That’s why the shiny.quetzio provides an easy way to link multiple questionnaires together with the use of QuetzioLink R6 class!

In this vignette there is an assumption that you already know how to construct questionnaires with Quetzio_create. If this assumption is wrong, you should first look into Create a questionnaire vignette.

How to set up linked questionnaires

If you already know how to create a questionnaire, this will be a breeze. The whole procedure is analogous to one used in Quetzio_create.

server call

You call QuetzioLink_create inside your server function.

It takes following arguments:

  • link_id - module id of you QuetzioLink shiny module.
  • - some Quetzio_create calls, containing configuration for the modules that you want to link together.
  • output_gsheet - logical value indicating, if you want to save the results automatically to some googlesheet. If set to TRUE, you will need to also provide:
    • output_gsheet_id - id of the googlesheet to upload answers to
    • output_gsheet_sheetname - name of the spreadsheet to upload answers to

To generate linked questionnaires, we can use question sources provided with the package (see documentation for quetzio_examples to get more information)

# assign to an object to access the state of link from you application
quetzio_link <- QuetzioLink_create(
  link_id = "linked_quetzios",
  # every questionnaire provided need to be named!
  first_quetzio = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$link_quetzio_1,
    # and you need to provide unique module ids
    module_id = "quetzio1"
  ),
  second_quetzio = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$link_quetzio_2,
    module_id = "quetzio2"
  ),
  third_quetzio = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$link_quetzio_3,
    module_id = "quetzio3"
  )
)
  • All module_ids and link_ids needs to be unique - just like during creation of regular shiny modules.
  • Remember to provide Quetzio_create() call directly in of the QuetzioLink_create(). You cannot assign them somewhere else and provide them afterwards.

ui call

To bind the interface into UI of your shinyApp, simply state following function. It takes only one argument: link_id.

# provide the same link_id as in server function
QuetzioLink_UI(
  link_id = "linked_quetzios"
)

Provide instructions and item descriptions!

As with using only single Quetzio, you can generate title, instructions and descriptions for individual questions. With single questionnaire you could also build the rest of the interface by providing it directly in the code of UI of your application.

It is much less straightforward to do with linked questionnaires - the linked UI will be changing, and you would also need to implement logic using shinyjs, conditionalPanel or in any other way.

Providing source for descriptions remedies it!

# we can use the link from previous example
quetzio_link <- QuetzioLink_create(
  link_id = "linked_quetzios",
  first_quetzio = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$link_quetzio_1,
    # just provide the description source by stating either
    # 'desc_object', 'desc_yaml' or 'desc_gsheet_id' and 'desc_gsheet_sheetname'
    desc_object = quetzio_examples$description_lists$link_quetzio_1,
    module_id = "quetzio1"
  ),
  second_quetzio = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$link_quetzio_2,
    desc_object = quetzio_examples$description_lists$link_quetzio_2,
    module_id = "quetzio2"
  ),
  third_quetzio = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$link_quetzio_3,
    desc_object = quetzio_examples$questions_lists$link_quetzio_3,
    module_id = "quetzio3"
  )
)

There are some objects you can get from object to which the linked questionnaires server was assigned. Taking above assignement as example:

  • QuetzioLink$completion() - the completion rate in form of numeric value between 0 and 1. It is generated as division:
    • number of completed questionnaires / number of linked questionnaires
  • QuetzioLink$message() list of message() of individual questionnaires
  • QuetzioLink$answers() list of answers() of individual questionnaires
  • QuetzioLink$quetzio_list gives you a way to access any element of object from any individual Quetzio object.

To update labels or selected values of items contained within QuetzioLink class you can use the same functions as with singular Quetzio: Quetzio_label_update and Quetzio_value_update. You need to provide additional argument. To learn about these functions read vignette Update created questionnaire

Reactive label update

You can update labels of any of linked questionnaires reactively with Quetzio_label_update function. It works basically the same like in with Quetzio object, but you need to also specify which questionnaire labels you want to update.

# create linked questionnaires
quetzio_link <- QuetzioLink_create(
  gender = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$gender_update,
    module_id = "updating_labels"
  ),
    quetzio_2nd = Quetzio_create(
    source_method = "raw",
    source_object = quetzio_examples$questions_lists$simple_quetzio,
    module_id = "second_in_link"
  ),
    link_id = "labels_link")

# if we have some input defined in the UI, we can update labels
# in reaction to it (in this example its inputId is 'gender')
# Its value need to be passed in a reactive object, though:
gender_react <- reactive(input$gender)

# after that - just make a call in your server
Quetzio_label_update(
  Quetzio = quetzio_link,
  name = "gender", # specify the name of questionnare
  trigger = gender_react,   # pass reactive (without parentheses!)
  source_method = "raw",   # specify source method and other args
  source_object = quetzio_examples$label_update$gender_update
)

You can also make something more complicated - for example get value to update labels of second (or any following questionnaires) on basis of answer of previous questionnaire.

quetzio_link <- QuetzioLink_create(
  gender_question = Quetzio_create(
   source_method = "raw",
   source_object = gender_1_item_source,
   module_id = "single_question"
  ),
  gender_update = Quetzio_create(
   source_method = "raw",
   source_object = quetzio_examples$questions_lists$gender_update,
   module_id = "update_gender"
  ),
  link_id = "labels_link")

# trigger need to be reactive
gender_react <- reactive({
  quetzio_link$answers()$gender_question$gender_item
})

# update labels method call
Quetzio_label_update(
  Quetzio = quetzio_link,
  # you need to provide the name of the quetzio_server in link
  # where you need to update labels
  name = "gender_update",
  # the trigger needs to be reactive, but without the parentheses
  trigger = gender_react,
  source_method = "raw",
  source_object = quetzio_examples$label_update$gender_update
)

Method is mostly identical to Quetzio_value_update, though you need to also provide name argument to choose which questionnaire values you want to update.

# update values on button press
observeEvent(input$update_vals, {
  Quetzio_value_update(
    Quetzio = quetzio_link,
    # you need to provide quetzio name in the link to update
    quetzio_name = "value_update",
    # you can use answers from one questionnaire to update another, though
    # the used values can be any other static named list
    values = quetzio_1st$answers()
    )
})