0

My goal is to be able to dynamically add range inputs onto a web page via javascript. I am using the following code for the sliders

<div class="slidecontainer">
    <input type="range" min="1" max="100" value="50" class="slider" id="myRange">
    <p>Value: <span id="demo"></span></p>
</div>
<script>
    var slider = document.getElementById("myRange");
    var output = document.getElementById("demo");
    output.innerHTML = slider.value;
    slider.oninput = function() {
        output.innerHTML = this.value;
    }
</script>

https://www.w3schools.com/howto/howto_js_rangeslider.asp

I have tried using innerHtml, document.createElement("input"), and templates to achieve this. I am able to draw the slider however I am unable to get the value to print and show any help would be appreciated on how to achieve this.

This is my most recent attempt

Script

function showContent() {
  var temp = document.getElementsByTagName("template")[0];
  var clon = temp.content.cloneNode(true);
  document.body.appendChild(clon);
}
Template.myTemplate.rendered = function(){
document.getElementById("slider").oninput = function() {
    myFunction()
};
function myFunction() {
   var val = document.getElementById("slider").value //gets the oninput value
   document.getElementById('output').innerHTML = val //displays this value to the html page
   console.log(val)
}
</script>

<template name="myTemplate">
 <input id="slider" type="range" min="50" max="100" step="10"  value="50">
 <output id="output">abc</output>
</template>

<button class = "button" onclick="showContent()">Copy text</button>

I also tried this thanks to MMDM which resulted in the 3 ranges drawing and 3 values being shown however, they do not update.

<script>
window.onload = function() 
{
var titles = ["demo1", "demo2", "demo3"];

for(var i = 0; i < 3; i++)
{
  var container = document.getElementsByClassName('slidecontainer')[0];
  var slider = document.createElement("input");
  slider.type = 'range';
  slider.value = 50;
  container.prepend(slider);
  container.innerHTML += ("<p>Value: <span id=" + titles[i] +"></span></p>")

  var output = document.getElementById(titles[i]);
  output.innerHTML = slider.value;

  slider.oninput = function() {
    output.innerHTML = this.value;
  }
}

}

</script>

<div class="slidecontainer">

</div>

3 Answers3

1

You can do something like:

window.onload = function() {
  var container = document.getElementsByClassName('slidecontainer')[0];
  var slider = document.createElement("input");
  slider.type = 'range';
  slider.value = 56;
  container.prepend(slider);

  var output = document.getElementById("demo");
  output.innerHTML = slider.value;

  slider.oninput = function() {
    output.innerHTML = this.value;
  }
}
<div class="slidecontainer">
  <p>Value: <span id="demo"></span></p>
</div>

Be careful! you must add your created element to the container otherwise you have no element there. And for more advanced onload approach see this topic

I hope it helps :)

EDIT:

I think you must attach events outside of that for loop and specify which element must have what functionality. I do that with snippet below:

window.onload = function() {
  function addClass(element, class_name) {
    arr = element.className.split(" ");
    if (arr.indexOf(name) == -1) {
      element.className += " " + class_name;
    }
  }

  var titles = ["demo1", "demo2", "demo3"];

  for (var i = 0; i < titles.length; i++) {
    var container = document.getElementsByClassName('slidecontainer')[0];
    var slider = document.createElement("input");
    slider.type = 'range';
    slider.value = Math.random() * 100;
    slider.setAttribute('data-lable-id', titles[i]);
    addClass(slider, 'range-sliders');
    container.prepend(slider);
    container.innerHTML += ("<p>Value: <span id=" + titles[i] + "></span></p>")

    var output = document.getElementById(titles[i]);
    output.innerHTML = slider.value;
  }

  var sliders = document.getElementsByClassName('range-sliders');
  var i;
  for (i = 0; i < sliders.length; i++) {
    (function(i) {
      var lbl_id = sliders[i].getAttribute('data-lable-id');
      if (lbl_id) {
        sliders[i].oninput = function() {
          document.getElementById(lbl_id).innerHTML = this.value;
        };
      }
    })(i);
  }
}
<div class="slidecontainer">

</div>
MMDM
  • 465
  • 3
  • 11
  • Thank you for the response, however, this doesn't achieve what I am after. I wish to dynamically load multiple sliders. As such I added a for loop to your code to run that 3 times and it did not work. – mathewcook123 Oct 24 '19 at 16:41
0

Before adding eventlistener wait for window load

 window.onload = function() {
   var slider = document.getElementById("myRange");
   var output = document.getElementById("demo");
   output.innerHTML = slider.value;

   slider.oninput = function() {
     output.innerHTML = this.value;
   }
 }
Ahmetcan Aksu
  • 53
  • 2
  • 10
0

According to your edit, Here is your answer:

window.onload = function() {
  document.querySelectorAll(".slidecontainer").forEach(function(element) {
    var slider = [...element.children].filter(x=> x.tagName == "INPUT")[0];
    var output = [...element.children].filter(x=> x.tagName == "P")[0];
    slider.oninput = function() {
      output.innerHTML = this.value;
    }
  });

}

The code will find every div that has class slidecontainer and it will take first input and first p element, the rest of the code is the same

Better code and div is:

<div class="slidecontainer">
    <input class="slider" type="range" min="1" max="100" value="50" class="slider" id="myRange">
    <br>  
    <span>Value:</span><span class="slider-value"></span>
</div>

<script>
window.onload = function() {
  document.querySelectorAll(".slidecontainer").forEach(function(element) {
    var slider = [...element.children].filter(x=> x.className == "slider")[0];
    var output = [...element.children].filter(x=> x.className == "slider-value")[0];
    slider.oninput = function() {
      output.innerHTML = this.value;
    }
  });
}
</script>

This code will find slidecontainer div and check input that has slider class and write input value to element that has slider-value class

Ahmetcan Aksu
  • 53
  • 2
  • 10