Watts-Lab / surveys

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

Adjust CSS styling for range slider ticks and labels #110

Closed JamesPHoughton closed 3 months ago

JamesPHoughton commented 1 year ago

We are using SurveyJS as a base for a react component library. (You shouldn't need to know anything about SurveyJS to do this task). We have modified SurveyJS's range slider component so that the user can add labels to the slider to indicate values. I need the CSS for these labels (and possibly the range slider component if necessary) to be updated. Right now what I have looks like this:

image

The relevant DOM elements are:

<div class="sliderContainer">
  <input id="sq_100i" class="sv-text slider sliderClicked" type="range" min="0" max="100" step="1" placeholder="" autocomplete="" aria-required="false" aria-label="How important is being a Republican to you?" aria-invalid="false" data-rendered="r" list="republicanImportance_slider_vals">
  <datalist id="republicanImportance_slider_vals" class="sliderLabels">
    <option value="0" class="sliderLabel" label="Not important at all"></option>
    <option value="25" class="sliderLabel" label="25"></option>
    <option value="50" class="sliderLabel" label="Moderately Important"></option>
    <option value="75" class="sliderLabel" label="75"></option>
    <option value="100" class="sliderLabel" label="Extremely Important"></option>
  </datalist>
</div>

and

<div class="sliderContainer">
  <input id="sq_101i" class="sv-text slider sliderClicked" type="range" min="0" max="12" step="1" placeholder="" autocomplete="" aria-required="false" aria-label="How many hours did you sleep last night?" aria-invalid="false" data-rendered="r" list="sleepHours_slider_vals">
  <datalist id="sleepHours_slider_vals" class="sliderLabels">
    <option value="0" class="sliderLabel" label="0"></option>
    <option value="10" class="sliderLabel" label="10"></option>
    <option value="12" class="sliderLabel" label="12"></option>
  </datalist>
</div>

I want it to look like this:

image

The code that controls these elements is found in this repo in src/customQuestionTypes/labeledRange.js and src/customQuestionTypes/labeledRange.css. I believe we should be able to make these changes just within the CSS file, but I'm ok with modifying the JS if necessary.

The major differences are:

Note:

Setup

  1. Fork and clone this repository
  2. Build the project by running the following command in the root directory (you need to have node installed):
    npm run build

    Then start the test suite by running:

    npm run test

    This will open cypress (it should load its needed dependencies) and then you can click "start component testing".

Run the spec called labeledRangeTest to view the component. Changes to the CSS and JS will get automatically applied to the page.

Please submit code by PR to this repo, and questions on this issue thread. =)

Resources

Styling for consistency across browsers:

Examples of styling ticks:

GH issue for adding the slider (work we have done so far): https://github.com/Watts-Lab/surveys/issues/1

JamesPHoughton commented 1 year ago

Posted to upwork: https://www.upwork.com/ab/applicants/1623799833964765184/job-details

horizonvert1027 commented 1 year ago

Hello, I have just seen your job post on Upwork. I can help you. horizonvert.pu@gmail.com

HUMAYOU-ALI-SARAL commented 1 year ago

Hi James, I have just submited my proposal to your job post, Kindly response as soon as possible, I can surely deliver your expected slider within an hour.

JamesPHoughton commented 1 year ago

Merged https://github.com/Watts-Lab/surveys/pull/112 (thanks @ amirrahman132132), which takes care of what I asked for above.

I dug deeper into the SurveyJS docs (https://surveyjs.io/form-library/documentation/api-reference/itemvalue#getPropertyValue) and it seems that it is the survey library rather than CSS which inserts the value as a default text string if you leave out the text.

We can tell if there is an actual true value specified by using label.locTextValue.isEmpty, which seems to return true if there is no value specified. So, I moved creating an empty string for the label value to the javascript:

      option.innerHTML = `
          <div class="each_label">
              <div class="tick"></div>
              <div class="label_value">${
                label.locTextValue.isEmpty ? " " : label.text
              }</div>
          </div>
        `;

This seems to allow us to omit the text string in order to leave a label off the slider tick altogether:

"valueLabels": [
            { "value": 0, "text": "0" },
            { "value": 2 },
            { "value": 4 },
            { "value": 6, "text": " " },
            { "value": 8 },
            { "value": 10, "text": "10" },
            { "value": 12, "text": "12" }
          ]
JamesPHoughton commented 1 year ago

Right now, the spacing of the ticks is set by just putting the first tick at the beginning, the last tick at the end, and then evenly spacing the remaining ticks. It would be nice to be able to set the spacing according to the actual value in the tick, rather than just its rank/order, so that you could have ticks placed arbitrarily on the bar. I've created an example survey to test this out:

{
  "type": "text",
  "inputType": "range",
  "name": "favoriteIrrational",
  "title": "What is your favorite irrational number?",
  "min": 1,
  "max": 4,
  "step": "any",
  "progressBar": true,
  "valueLabels": [
    { "value": 1.4142, "text": "√2" },
    { "value": 1.618, "text": "φ" },
    { "value": 2.7182, "text": "e" },
    { "value": 3.1415, "text": "π" }
  ]
}

currently it looks like this:

image

But it should look more like this: image

This seems to be what is happening in this example:

JamesPHoughton commented 10 months ago

@gumillie222 can you just read over this issue and check if its complete?

gumillie222 commented 6 months ago
Screenshot 2024-03-30 at 6 46 27 PM