Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drag drop question added from sortable #163

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

saudiwin
Copy link

@saudiwin saudiwin commented Jan 3, 2025

I was able to get the sortable drag/drop question to work without too much trouble. I ported sortable to a separate package (sortsurvey, see https://github.com/saudiwin/sortable_survey) and created a rank_list question as rank_list_survey. I then added this widget as a "mc_drag_drop" option in sd_question. The folder test_rank_question contains an example.

It seems to work fairly well. If sortable never addresses the issue, I could pare down sortsurvey so that it only contains the bare bones to run this particular question.

The only thing that would remain is to consider exposing more options--there are a whole bunch. Happy to keep working on this.

@saudiwin
Copy link
Author

saudiwin commented Jan 3, 2025

There are multiple commits as I attempted to just use sortable, thought it worked, then realized it actually didn't and went back to the ported package.

@jhelvy
Copy link
Collaborator

jhelvy commented Jan 3, 2025

Yeah that's more what I was suggesting on the discussion you started. I was thinking we could extract the relevant parts needed from {sortable} for this one specific question type and just bring those into {surveydown}. If the whole {sortable} package isn't really needed, then this might be sufficient since it's a pretty specific use case. And it would avoid the dependency and potential issues in the future if they change the package in ways that no longer work with {surveydown}.

What sorts of other features / options are available? Are there any that would make sense as a question type?

Also, I'm not sure if "mc_drag_drop" is the best name for this question type. When I look at the types of question widgets supported by SurveyJS, they call this a "ranking" type question, which I think is accurate because it's only for ranking things. MC is multiple choice, where you're making a choice, but this is just ranking the options.

Another type that looks attractive is "Select items to rank", which might be possible using sortable.

@saudiwin
Copy link
Author

saudiwin commented Jan 3, 2025

OK sounds like we are on the same page then. I made a new package (sortsurvey) because it seemed like a good idea to keep the code modular. That way if there was some issue with sortable down the line, and people weren't using the drag/drop question, then surveydown would remain viable.

They seem to have most of the sortable options implemented. See the github here:

https://github.com/rstudio/sortable

I'll work on adding the others as options. Seems like "mc_rank" would work? And "mc_rank_bucket"?

@jhelvy
Copy link
Collaborator

jhelvy commented Jan 3, 2025

Cool. Yeah I'm good with this approach. We could add your {sortsurvey} package as a dependency that only lives here on GitHub (I'm assuming you wouldn't want to publish it to CRAN).

In general I don't think any of these should have "mc" in the name of the question type because these questions are rank questions, not choice questions. So I think you can just leave the "mc" part off.

…rrectlly in shiny file (some inheritance issue)
@jhelvy
Copy link
Collaborator

jhelvy commented Jan 4, 2025

Okay I finally got a chance to look more at the docs for sortable, and for sure I think we should support both the rank list and the bucket list as question types. And I think the "type" names could be as simple as rank_list and bucket_list.

I also saw all the other super cool things out there like shinyjqui. There are lots of things that could be done with this. But for now I'll saw sortable seems like a solid target to work with for supporting more interactive question widgets.

@saudiwin
Copy link
Author

saudiwin commented Jan 7, 2025

OK I renamed the questions so they are now "rank_list" and "bucket_list". I also added a new function "bucket_list_survey" that does the same basic modification as "rank_list_survey" from sortable.

bucket_list_survey() works fine in a quarto doc but it doesn't produce a valid HTML widget from sd_question(). I think the problem is that the bucket_list object is a list with rank_list HTML widgets inside. Each of those widgets has its own input ID. At present the code is setting that input ID for the bucket_list object as a whole but the rank_list objects have separate IDs set internally.

These can also be set but I wanted to flag this as I'm not sure of the best way to do that. This will likely require some further modifications.

Alternatively, we could make our own bucket_list type function as their function is essentially a wrapper around rank_list.

Another more minor issue I encountered is that I could not get bucket_list to appear in horizontal model in a quarto doc (i.e. both buckets side by side). In a quarto doc, it was always in vertical mode. I tried using two-column layout in quarto but to no avail (it also doesn't matter what width you set on the widgets either). So not sure how to get around this one although it's not a dealbreaker in any case.

@saudiwin
Copy link
Author

saudiwin commented Jan 7, 2025

The other thing we don't have working out of the box yet is reactivity with sd_output. Apparently they are adding a helper function for updating ranked lists:

https://github.com/rstudio/sortable/blob/main/inst/shiny/update_rank_list_method/app.R

and there is a more involved way of doing it:

https://github.com/rstudio/sortable/blob/main/inst/shiny/update_rank_list_ui/app.R

@saudiwin
Copy link
Author

saudiwin commented Jan 7, 2025

Also finally it would be great to add numbers to the options so the user can see which is No. 1, 2, etc. Seems like that should be simple CSS adjustment (he says before looking at it).

@jhelvy
Copy link
Collaborator

jhelvy commented Jan 7, 2025

Can you help me understand what you're trying to do in terms of implementing the rank_list and bucket_list question types? There are two ways to generate a question:

  1. In the survey.qmd file, add a code chunk and use the sd_question() function.
  2. In the app.R file, use the sd_question() function inside the server() function, then in the survey.qmd file add a code chunk and use the sd_output(id) function where you want the question to display, matching the id to the id value used in sd_question() in the server.

The second option is the "reactive" way to do it, and for some situations this has to be done. For example, in this section of the docs describing how to display randomized question labels, the labels are randomly defined in the server along with the question, then sd_output() is used in the survey.qmd file to display the question.

We've also had to use this approach for certain types of shiny widgets as they just don't render properly in Quarto. For this purpose, we made a sd_question_custom() function that allows you to insert any html widget you want and then have the value(s) returned by that widget stored in the resulting survey data. In this case, this may be the approach you need to use if you're having trouble defining these sortable widgets inside the Quarto document. If that works, then you wouldn't need to modify the {sortable} package at all - just define the widgets in the app.R file then use sd_question_custom() to store the value in the data. If you give that approach a try and it works, then we have at least one way to do it.

Still, given how common this type of question is, it would be much nicer if a user could just use sd_question(type = "rank_list") directly in the survey.qmd file.

@saudiwin
Copy link
Author

Hi John -

So the issue with the latter. The rank_list and bucket_list work great (or mostly great) in the sd_question() function. It's only when using reactivity with the sd_output function that it doesn't work. Specifically, I tried setting the choices on the server side and it worked but then I could no longer drag and drop the choices in the survey.

I can send you a reprex for this if you need it, I would just need to clean the code a bit as it's from a current survey I'm testing. It's not a huge issue for what I'm working on at present but obviously we'd need to figure it out before moving it into the package proper.

@jhelvy
Copy link
Collaborator

jhelvy commented Jan 11, 2025

Hmm, my guess is that it requires some JS libraries to work. When you use it in the survey.qmd file with sd_question, Quarto probably adds the necessary dependencies when it renders, and those dependencies get captured and brought into the shiny app. When you instead define it in the app.R file, those dependencies may not be registered. At least that's my suspicion for what is going on.

One way to test that is to make a survey with two rank_list questions - one in the survey.qmd file, and one defined in the app.R file. Give them different options so you can distinguish them. I suspect that both will show up this way, because the required libraries will get loaded due to the one being defined in the survey.qmd file.

It would help if you could provide a simple reprex for each case.

@jhelvy
Copy link
Collaborator

jhelvy commented Jan 18, 2025

FYI, related conversation on Bluesky on the bucket list:

https://bsky.app/profile/willngiam.bsky.social/post/3lfzf4o4b6c22

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants