Reactive Labels and options depending on previous answers #117
-
DescriptionRight now, I'm testing your wonderful project for our use cases. One thing we use quite often, is the conditional display of questions labels or answers. For example, when the respondent is interested in dating men, I would like to change the text of the following question slightly to change just one or two words (e.g. "What do you like about {men}?"). |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 3 replies
-
Idea 1Put the question in the markdown and leave the actual question label blank. This works okay, but it's less ideal as the question label is outside of the question box. It looks like this: Here's how you could make this: SURVEY: ---
format: html
echo: false
warning: false
---
```{r}
library(surveydown)
```
::: {#page1 .sd-page}
```{r}
sd_question(
type = "mc",
id = "date_type",
label = "Do you date men or women?",
option = c(
"Men" = "men",
"Women" = "women"
)
)
sd_next()
```
:::
::: {#page_id .sd-page}
What do you like about dating `r sd_output('date_type', type = 'value')`?
```{r}
sd_question(
type = "textarea",
id = "likes",
label = ""
)
sd_next()
```
:::
::: {#end .sd-page}
This is the end of the survey
```{r}
sd_close()
```
:::
APP: library(surveydown)
db <- sd_database(ignore = TRUE)
server <- function(input, output, session) {
sd_server(db = db)
}
shiny::shinyApp(ui = sd_ui(), server = server)
|
Beta Was this translation helpful? Give feedback.
-
Idea 2Define two separate questions in your Here's how you could make this: SURVEY: ---
format: html
echo: false
warning: false
---
```{r}
library(surveydown)
```
::: {#page1 .sd-page}
```{r}
sd_question(
type = "mc",
id = "date_type",
label = "Do you date men or women?",
option = c(
"Men" = "men",
"Women" = "women"
)
)
sd_next()
```
:::
::: {#page_id .sd-page}
```{r}
sd_output('likes_men', type = 'question')
sd_output('likes_women', type = 'question')
sd_next()
```
:::
::: {#end .sd-page}
This is the end of the survey
```{r}
sd_close()
```
::: APP: library(surveydown)
db <- sd_database(ignore = TRUE)
server <- function(input, output, session) {
sd_question(
type = "textarea",
id = "likes_men",
label = "What do you like about dating men?"
)
sd_question(
type = "textarea",
id = "likes_women",
label = "What do you like about dating women?"
)
sd_show_if(
input$date_type == "men" ~ "likes_men",
input$date_type == "women" ~ "likes_women"
)
sd_server(db = db)
}
shiny::shinyApp(ui = sd_ui(), server = server) |
Beta Was this translation helpful? Give feedback.
-
Idea 3(IMO the simplest / best solution) Use sd_question(
type = "mc",
id = "date_type",
label = "Do you date men or women?",
option = c(
"Men" = "men",
"Women" = "women"
)
) Then on the next page you could insert the response to the first question in the label of the follow-on question like this: sd_question(
type = "textarea",
id = "likes",
label = glue::glue("What do you like about dating {sd_output('date_type', type = 'value')}?")
) Here's a full example: SURVEY: ---
format: html
echo: false
warning: false
---
```{r}
library(surveydown)
```
::: {#page1 .sd-page}
```{r}
sd_question(
type = "mc",
id = "date_type",
label = "Do you date men or women?",
option = c(
"Men" = "men",
"Women" = "women"
)
)
sd_next()
```
:::
::: {#page_id .sd-page}
```{r}
sd_question(
type = "textarea",
id = "likes",
label = glue::glue("What do you like about dating {sd_output('date_type', type = 'value')}?")
)
sd_next()
```
:::
::: {#end .sd-page}
This is the end of the survey
```{r}
sd_close()
```
::: APP: library(surveydown)
db <- sd_database(ignore = TRUE)
server <- function(input, output, session) {
sd_server(db = db)
}
shiny::shinyApp(ui = sd_ui(), server = server) |
Beta Was this translation helpful? Give feedback.
-
Okay I left 3 ideas here on how to do this. The simplest one by far is idea 3, but I'm keeping all of these just in case there are others who may find these approaches helpful.
|
Beta Was this translation helpful? Give feedback.
-
I really appreciate the effort you guys spend in this project. So, thanks for the quick and extensive response. I also think this could be helpful for others. Nevertheless, I still miss an additional solution where I can access and use the value for further conditional selections. Let me provide a more profound but fictional example: SURVEY: sd_question(
type = "mc",
id = "date_type",
label = "Do you date men or women?",
option = c(
"Men" = "men",
"Women" = "women"
)
)
lab_date_type <- date_type$value # fictional way of accessing the given answer
lab_pref_type <- if (lab_date_type == "men") "masculanity" else "feminity"
sd_question(
type = "mc",
id = "date_preference",
label = glue::glue{"Since you are interesseted in {lab_date_type}, do you like {lab_pref_type}""),
option = c(
glue::glue("Yes, I like {lab_pref_type}") = "date_pref_yes",
glue::glue("No, I don't like {lab_pref_type}") = "date_pref_no"
)
) I hope this makes my needs a little bit more clear. I'm looking for a way to use a respondent's answer for further question and answer modeling, and I can't just prolong with the "simple" answer. Could also be the case, if it's a condition on multiple possible answers (e.g. male & diverse vs. female). |
Beta Was this translation helpful? Give feedback.
-
Okay I see what you're trying to do. The In this case, you're trying to use the response value itself to do something with it, like create some other object based on the value chosen. In this case, you would have to run this logic in the This works for the question label, but we don't have this supported yet for the question options. That's something we could probably add though. Here's an example: SURVEY: ---
format: html
echo: false
warning: false
---
```{r}
library(surveydown)
```
::: {#page1 .sd-page}
```{r}
sd_question(
type = "mc",
id = "date_type",
label = "Do you date men or women?",
option = c(
"Men" = "men",
"Women" = "women"
)
)
sd_next()
```
:::
::: {#page2 .sd-page}
```{r}
# Create local objects to display
date_type <- sd_output('date_type', type = 'value')
pref_type <- textOutput('lab_pref_type', inline = TRUE)
sd_question(
type = "mc",
id = "date_preference",
label = glue::glue("Since you are interested in {date_type}, do you like {pref_type}"),
option = c(
"Yes" = "yes",
"No" = "no"
)
)
sd_next()
```
:::
::: {#end .sd-page}
This is the end of the survey
```{r}
sd_close()
```
::: APP: library(surveydown)
db <- sd_database()
server <- function(input, output, session) {
observe({
result <- "feminity"
type <- input$date_type
if (length(type) > 0) {
if (type == "men") { result <- "masculanity" }
}
output$lab_pref_type <- renderText(result)
})
sd_server(db = db)
}
shiny::shinyApp(ui = sd_ui(), server = server) Notice there's a good bit of shiny machinery here needed to make this work, namely this bit: observe({
result <- "feminity"
type <- input$date_type
if (length(type) > 0) {
if (type == "men") { result <- "masculanity" }
}
output$lab_pref_type <- renderText(result)
}) Here what we're doing is setting up an observer to "watch" the It's a good bit of work, but this is one way to make this happen. If you try to do the same thing for the options label, it won't render properly, at least not yet. I'll look into whether it's possible to modify the option label with a reactive value just like we did with the label. |
Beta Was this translation helpful? Give feedback.
-
I added a similar (but slightly simpler) example to the documentation page on reactivity. Hopefully that will be helpful for anyone else trying something like this. |
Beta Was this translation helpful? Give feedback.
Btw, here's another way to define the server function in the app.R file: