Closed JamesPHoughton closed 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.
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.
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...
Added the range slider and some custom styling/handling. What we need now is just some CSS wizardry to make it look good:
This should live in the /src/customQuestionTypes/labeledRange.css
file.
progressBar
)sliderClicked
)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.
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:
Green underbar is actually a horizontal scroll bar, because the range slider is too wide for its container, and sticks its ears out the end. Setting the width to 99% of the container means that there isn't an overflow.
Turns out we actually want to enable the thumb on mouseDown, not when a value has been entered (which seems to happen on mouseUp?) Also, the afterRender
method only gets called once, so we can't count on it to add the class label without a callback anyways. The solution is to add an event listener to the slider:
slider.addEventListener("mousedown", () => slider.classList.add("sliderClicked"));
name: "valueLabels",
type: "itemvalues",
Some examples of styling ticks:
Current status:
Still to do:
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.