-4

I have issues when retrieving the data. When creating the data, I have a slider and which is attatched to a EventListener. The slider appears only after something has been selected from a select box. The problem is when I do it in the same way for the retrival, only the item which is added last has a working EventListener. Is this because both of them are added on the same time? When creating the data, the eventhandlers are created one at the time, and there it works.. Any help would be appreciated.

The following HTML code is added by selecting a item from a select list.

<div class='range-slider'>
   <span id = 'rs-bullet_skill"+ id + "' class='rs-label' > </span >
   <input id ='hidden_skillID"+id+"' class='hidden_skill' 
   name='Skills["+ minFree + "].Id' value='" + id +"' hidden >
  <input class='rs-range' type='range' id='slider_skill"+ id + "' 
  name= Skills[" + minFree + "].LevelOfSkill value='0' min='0' max='100'>
</div>

I have checked that the Ids are similiar.

function showSliderValue() 
{
    rangeBullet.innerHTML = rangeSlider.value;
    var bulletPosition = (rangeSlider.value / rangeSlider.max);
    rangeBullet.style.left = (bulletPosition * 578) + "px";
}

for (var i = 0; i < used_skill_ids.length; i++) 
{
    var rangeSlider = document.getElementById("slider_skill" + 
    used_skill_ids[i]);
    var rangeBullet = document.getElementById("rs-bullet_skill" + 
    used_skill_ids[i]);
    rangeSlider.addEventListener("input", showSliderValue, false);
}

The working example runs when the select is updated ($(SelectSkills).on('change', function () .. here is a image of how it looks when adding them from the select list imgur.com/a/2iNC3w0.

The issue is when more than one of these listnerers are added, and this will happen if someone has registered more than one, and wants to edit it.

Then my script tries to add them all at once. Markmoxx example solved the actions, but now the sliders are connected (https://i.stack.imgur.com/7rzkh.jpg)

The first two sliders have have the above described code.

The third and fourth have what Markmoxx proposed :

function showSliderValue(e, rangeBullet) {
  rangeBullet.innerHTML = e.target.value;
  var bulletPosition = (e.target.value / e.target.max);
  rangeBullet.style.left = (bulletPosition * 578) + "px";
}

for (var i = 0; i < used_skill_ids.length; i++) {
  var rangeSlider = document.getElementById("slider_skill" + 
  used_skill_ids[i]);
  var rangeBullet = document.getElementById("rs-bullet_skill" + 
  used_skill_ids[i]);
  rangeSlider.addEventListener("input", function(e) {
  showSliderValue(e, rangeBullet);
  });
}

Hope this is a better description of the problem.

Atle Kristiansen
  • 707
  • 7
  • 28

2 Answers2

6

You are running into a scoping issue by using var (instead of let); as well, you are redefining the 'range*' variables every time through the loop. I think what you want is something more like the following :

for (let i = 0; i < used_ids.length; i++) {

  document
    .getElementById("slider" + used_ids[i])
    .addEventListener(
      "input",
      () => {
        let
          rangeBullet = document.getElementById("rs-bullet" + used_ids[i]),
          rangeSlider = document.getElementById("slider" + used_ids[i]);

        rangeBullet.textContent = rangeSlider.value;
        rangeBullet.style.left = ((rangeSlider.value / rangeSlider.max) * 578) + "px";
      }
    );
}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
do or do not
  • 146
  • 1
  • 5
2

It's because when the loop executes, on the last iteration, it sets the value of rangeBullet to document.getElementById("rs-bullet_skill" + used_skill_ids[used_skill_ids.length - 1]), and similarly with rangeSlider. So when the event listener is called on any of the rangeSliders, it uses those values from the last iteration for the variables rangeBullet and rangeSlider.

It might be better to use an inline function, so you can pass a parameter to the showSliderValue function, like so:

function showSliderValue(e, rangeBullet) {
    rangeBullet.innerHTML = e.target.value;
    var bulletPosition = (e.target.value / e.target.max);
    rangeBullet.style.left = (bulletPosition * 578) + "px";
}

for (var i = 0; i < used_skill_ids.length; i++) {
    var rangeSlider = document.getElementById("slider_skill" + 
    used_skill_ids[i]);
    var rangeBullet = document.getElementById("rs-bullet_skill" + 
    used_skill_ids[i]);
    rangeSlider.addEventListener("input", function(e) {
        showSliderValue(e, rangeBullet);
    });
}
markmoxx
  • 1,492
  • 1
  • 11
  • 21
  • 1
    That made it possible to use both sliders, but they change the same number. The sliders are not supposed to be attached. Like this: https://imgur.com/a/2iNC3w0 – Atle Kristiansen Feb 10 '19 at 21:36