Watts-Lab / surveys

Library of surveys for deliberation experiments
MIT License
3 stars 4 forks source link

Implement non-anchoring slider #1

Closed JamesPHoughton closed 1 year ago

JamesPHoughton commented 2 years ago

As an experiment designer, I want to be able to include a slider in SurveyJS surveys so that we can ask questions like "feeling thermometers". One hazard with sliders is that the slider handle serves as an "anchor" for the response that participants will make, and so may bias the outcomes of the survey.

In empirica (V1 at least) there is a slider with no handle until the participant clicks on the bar. This is a styling wrapper around blueprint's slider. SurveyJS has two slider plugins (Nouislider and bootstrap slider) which we may be able to modify with similar styling changes to use in our surveys.

willschulz commented 1 year ago

Could we just set the slider to start out at the center position by default? This is how I've implemented sliders in Qualtrics surveys before, and though I agree handle-less might be even better, center-default should be fine.

JamesPHoughton commented 1 year ago

There is a slider input built into HTML5, that is well supported by modern browsers. There are some nice examples of using a datalist to add scale labels to a slider. There are also nice demos of CSS Styling a slider.

This should be easy. Unfortunately, SurveyJS doesn't use what seems like a fairly straightforward solution.

SurveyJS does allow some sliders as third party plugins:

But they are old, probably because they have been replaced by the built-in <input type="range/> in most applications. They also depend on some heavyweight libraries (bootstrap or Jquery) which we would otherwise not need to include in our libraries. It would be lovely not to have to add lots of dead weight (load time, complexity, etc) to our code.

We could add a custom widget to our surveys library that we could import in the surveyFactory, using the input-range component. This would also let us specify the custom CSS needed to hide the handle.

The API for a custom widget is a little confusing (which may be why there aren't more plugins). There are a few examples. Documentation here and here.

JamesPHoughton commented 1 year ago

This library documentation is really bad. Turns out you can do a range slider by using a single input question with type "range" (not in docs) but you can't actually set what the endpoints are. So, close to useless?

https://github.com/surveyjs/survey-library/issues/444#issuecomment-324552992

It does mean we should be able to just modify the range component rather than having to create one from scratch, however...

JamesPHoughton commented 1 year ago

Added the range slider and some custom styling/handling. What we need now is just some CSS wizardry to make it look good: Screen Shot 2023-01-30 at 10 57 01 AM

This should live in the /src/customQuestionTypes/labeledRange.css file.

Todo:

Resources:

You can display the component by running the test script npm run test in the package root, and then using the "component test" suite, run the test/labeledRangeTest.json cypress test to display the component in the browser.

JamesPHoughton commented 1 year ago

Also, for some reason the dataList isn't using the right values, so that two questions on the same page with different tickmarks are showing up using the last element's tickmarks. (Even though the min/max/step are working properly).

"elements": [
        {
          "type": "text",
          "inputType": "range",
          "name": "republicanImportance",
          "title": "How important is being a Republican to you?",
          "description": "Below is a range from 0 to 100 indicating how important this is to you. Click on any space within this range and a bar will appear. Feel free to move that bar around to the number that best represents your answer.",
          "min": 0,
          "max": 100,
          "step": 1,
          "valueLabels": [
            { "value": 0, "text": "Not important at all" },
            { "value": 25, "text": "" },
            { "value": 50, "text": "Moderately Important" },
            { "value": 75, "text": "" },
            { "value": 100, "text": "Extremely Important" }
          ]
        },
        {
          "type": "text",
          "inputType": "range",
          "name": "sleepHours",
          "title": "How many hours did you sleep last night?",
          "min": 0,
          "max": 12,
          "step": 1,
          "progressBar": true,
          "valueLabels": [
            { "value": 0, "text": "0" },
            { "value": 10, "text": "10" },
            { "value": 12, "text": "12" }
          ]
        }
      ]

Shows: image

JamesPHoughton commented 1 year ago
JamesPHoughton commented 1 year ago
JamesPHoughton commented 1 year ago

Some examples of styling ticks:

JamesPHoughton commented 1 year ago

Current status:

image

Still to do:

JamesPHoughton commented 1 year ago

Closed by https://github.com/Watts-Lab/surveys/pull/112