Program EQ-5D VAS Scale | Experience Community
Skip to main content
Solved

Program EQ-5D VAS Scale

  • January 29, 2019
  • 34 replies
  • 1364 views

Show first post

34 replies

Forum|alt.badge.img+7
  • Level 2 ●●
  • January 15, 2022

Please note that Euroqual now have a Qualtrics version available, so this coding probably won't be necessary, it will be in-built in the provided survey - At last/About Time!
https://euroqol.org/eq-5d-instruments/eq-5d-5l-available-modes-of-administration/self-complete-for-use-in-qualtrics/


Forum|alt.badge.img+1
  • February 3, 2022

amartin123 Did you ever figure this out? I'm getting the same issue.


Forum|alt.badge.img+1
  • March 23, 2022

Hey Guys - jeffreyohl & amartin123 I have just the same issue - have you figured out a solution jet? I`m at my wit's end.... Thanks a lot, I'm glad for any help or tips.


Forum|alt.badge.img+22
  • Level 7 ●●●●●●●
  • March 24, 2022

Screenshot_20220324-073154__01.jpgDelete the  


Forum|alt.badge.img+1
  • March 24, 2022

ahmedA Thanks a lot for coming back to my question. Perfect, it works so well now :)


Forum|alt.badge.img+1
  • April 5, 2022

Hi
This thread is amazing & has been super helpful, but I am running into the same issues as several others and the solutions mentioned so far are not resolving it. I'm adapting the text slightly as want the vertical slider for a social ladder not the Euroqual measure but that shouldn't be an issue. Everything looks good except there is no slider!
Screenshot (5).pngCreated a question using Constant Sum, one statement, vertical.

Look and Feel> General> Header updated:

https://cdn.jsdelivr.net/npm/nouislider@14.6.3/distribute/nouislider.min.css"
 rel="stylesheet" />
<link href="
https://cdn.jsdelivr.net/npm/nouislider@14.6.3/distribute/nouislider.min.css"
 rel="stylesheet" type="text/css" /><script src="
https://cdn.jsdelivr.net/combine/npm/nouislider@14,npm/wnumb@1"></script>
 src="
">https://cdn.jsdelivr.net/combine/npm/nouislider@14.6.2,npm/wnumb@1.2.0">

No rouge AT all @
JavaScript updated

Qualtrics.SurveyEngine.addOnload(function()
{ var vSlider = document.getElementById('uiSlider');
  noUiSlider.create(vSlider, {

   start: 50,

   step: 1,

   direction: 'rtl',

   orientation: 'vertical',  

   range: {

     min: 0,

     max: 100

   },

   format: wNumb({

    decimals: 0

   }),

    // Show a scale with the slider

    pips: {

      mode: 'positions',

      values: [0,10,20,30,40,50,60,70, 80,90,100],

      stepped: true,

    }

  });

   

  var inputNumber = document.getElementById('QR~'+this.questionId+'~1');

  vSlider.noUiSlider.on('update', function (values, handle) {

    inputNumber.value = values[handle];

  });

  inputNumber.addEventListener('change', function () {

   vSlider.noUiSlider.set([null, this.value]);

  });

  inputNumber.setAttribute('readonly',true)

});


HTML view updated:
Imagine that this scale pictures how society is set up.

At the top of the scale are the people who are best off – they have the most money, the highest amount of schooling, ant the jobs that bring the most respect.

At the bottom are people who are the worst off – they have the least money, little or no education, no job or jobs that no one wants or respects.

Now think about your family.
Please tell us where you think your family would be on this scale.


  
 
 
  
 
 
  
 
 


  
The best off you can imagine

  

  
The worst off you can imagine



I am totally lost its been hours, any help or advice much appreciated!😅


TomG
Level 8 ●●●●●●●●
Forum|alt.badge.img+27
  • Level 8 ●●●●●●●●
  • April 5, 2022

Looks like you edited the header in Rich Text format, so some of the characters got replaced with html entities (

" < >
). You'll have to fix it. You should edit the header ONLY in source mode.


Forum|alt.badge.img+1
  • April 6, 2022

Thanks TomG you clearly know what your talking about.
Sadly no such luck, I couldn't spot " < > but I did remove " > < from the latter end of the Look and Feel Header code and it did not work. :( 
Essentially with your advice I tried running - this created visible code in the preview header or the questionnaire but no slider.


<link href="https://cdn.jsdelivr.net/npm/nouislider@14.6.3/distribute/nouislider.min.css"rel="stylesheet" type="text/css" /><script src="https://cdn.jsdelivr.net/combine/npm/nouislider@14,npm/wnumb@1/script>

I've tried to change the Look and Feel code several time using different formats 


and 

None of which worked at generating the slider...


Forum|alt.badge.img
  • January 8, 2026

Hello, how is one able to put force response in this question type if it is constant sum? I thought that costume validation would be the solution so I updated the Java Script so that the value in the text box would be empty at the start and appear when you move the slider handle. This did not work and now i fear i have a very long JS. Would GREATLY appreciate someones support with this!! ​@TomG would you be able to help me with this? Pasting my JS below:

 

 

Qualtrics.SurveyEngine.addOnload(function() {
  var qid = this.questionId;
  var q = document.getElementById(qid);
  if (!q) { console.error('Question container not found'); return; }

  var sliderContainer = q.querySelector('#uiSlider');
  if (!sliderContainer) {
    console.error('uiSlider element not found inside question. Make sure your RCE contains <div id="uiSlider"></div>');
    return;
  }

  // Cleanup any previous children
  while (sliderContainer.firstChild) sliderContainer.removeChild(sliderContainer.firstChild);

  // Robust lookup for Qualtrics input (many possible DOM patterns)
  function findQualInput() {
    var byId = document.getElementById('QR~' + qid + '~1');
    if (byId) return byId;
    var byQuery = q.querySelector('input[type="text"], input[type="number"], input[type="tel"], textarea');
    if (byQuery) return byQuery;
    var byName = q.querySelector('input[name^="QR"], input[name*="' + qid + '"]');
    if (byName) return byName;
    return null;
  }

  var qualInput = findQualInput();
  if (qualInput) {
    try { qualInput.readOnly = false; } catch(e){}
    // Clear at load so box is empty until user moves slider
    qualInput.value = '';
    // Do not notify change here on purpose
    qualInput.style.opacity = qualInput.style.opacity || '';
  } else {
    console.warn('Qualtrics input not found; script will use Embedded Data fallback VAS_' + qid);
  }

  function notifyInput(el) {
    try { el.dispatchEvent(new Event('input', { bubbles: true })); } catch(e){}
    try { el.dispatchEvent(new Event('change', { bubbles: true })); } catch(e){}
  }
  function clampInt(x){ x = parseInt(String(x).replace(/[^\d\-]/g,''),10); if (isNaN(x)) x = 0; if (x < 0) x = 0; if (x > 100) x = 100; return x; }

  // Track whether user has interacted
  var userHasMoved = false;

  // Function to write value (writes to Qualtrics input if present + Embedded Data fallback)
  function writeValue(v) {
    v = clampInt(v);
    qualInput = qualInput || findQualInput(); // re-resolve in case Qualtrics rendered it late
    if (qualInput) {
      qualInput.value = String(v);
      notifyInput(qualInput);
    }
    try { Qualtrics.SurveyEngine.setEmbeddedData('VAS_' + qid, String(v)); } catch(e){}
    console.log('VAS write:', qid, v);
  }

  // Build slider: prefer noUiSlider (if available) else native fallback
  if (typeof noUiSlider !== 'undefined' && typeof wNumb !== 'undefined') {
    var target = document.createElement('div');
    target.id = 'uiSlider_inst_' + qid;
    target.style.height = '400px';
    sliderContainer.appendChild(target);

    try {
      noUiSlider.create(target, {
        start: 50, // visual only
        step: 1,
        orientation: 'vertical',
        direction: 'rtl',
        range: { min: 0, max: 100 },
        format: wNumb({ decimals: 0 }),
        pips: { mode: 'values', values: [0,10,20,30,40,50,60,70,80,90,100], density: 4 }
      });

      // Mark user interaction upon start (covers clicks/drags)
      target.noUiSlider.on('start', function() { userHasMoved = true; });

      // Update while moving only if userHasMoved
      target.noUiSlider.on('update', function(values, handle) {
        var v = clampInt(values[handle]);
        if (userHasMoved) writeValue(v);
      });

      // Ensure final persisted on end
      target.noUiSlider.on('end', function(values, handle) {
        var v = clampInt(values[handle]);
        writeValue(v);
      });

      console.log('noUiSlider ready (visual 50, input empty until moved).');
    } catch (e) {
      console.warn('noUiSlider init error — falling back to native. Error:', e);
      while (sliderContainer.firstChild) sliderContainer.removeChild(sliderContainer.firstChild);
      initNative();
    }
  } else {
    initNative();
  }

  // Native fallback initializer
  function initNative() {
    var wrapper = document.createElement('div');
    wrapper.style.height = '400px';
    wrapper.style.display = 'flex';
    wrapper.style.alignItems = 'center';
    wrapper.style.justifyContent = 'center';

    var native = document.createElement('input');
    native.type = 'range';
    native.id = 'vasRange_' + qid;
    native.min = 0; native.max = 100; native.step = 1; native.value = 50; // visual start
    native.style.transform = 'rotate(-90deg)';
    native.style.width = '400px';
    native.style.webkitAppearance = 'none';
    native.style.background = 'transparent';
    native.style.height = '18px';
    native.style.margin = '0 12px';

    wrapper.appendChild(native);
    sliderContainer.appendChild(wrapper);

    // pointerdown to mark interaction (covers mouse/touch)
    native.addEventListener('pointerdown', function(){ userHasMoved = true; });

    // write only after userHasMoved
    native.addEventListener('input', function() {
      var vv = clampInt(this.value);
      if (userHasMoved) writeValue(vv);
    });

    // also write final on change
    native.addEventListener('change', function() {
      var vv = clampInt(this.value);
      writeValue(vv);
    });

    console.log('Native slider created (visual 50, input empty until moved).');
  }

  // Ensure final value gets written on unload/next (if user moved)
  Qualtrics.SurveyEngine.addOnUnload(function() {
    var current = null;
    var inst = q.querySelector('#uiSlider_inst_' + qid);
    if (inst && inst.noUiSlider) current = inst.noUiSlider.get();
    else {
      var nat = q.querySelector('#vasRange_' + qid);
      if (nat) current = nat.value;
    }
    if (userHasMoved && current !== null) {
      var v = clampInt(current);
      writeValue(v);
      console.log('OnUnload wrote final VAS value', v);
    } else {
      console.log('OnUnload: userHasMoved=', userHasMoved, ' nothing to write.');
    }
  });

});