Search code examples
javascriptjavascript-objectscustom-data-attribute

How do I change the contents of an unordered list using Data attributes and JS objects?


I have dynamic list items that need to change based on the input of a range slider. I am using an in my HTML and the

  • have data attributes. I created JS objects that I would like to use to populate the list depending on where the slider is.

    Here is my HTML:

    <p>Equivelant impact to:</p>
          <ul id="impact-list">
            <li data-miles></li>
            <li data-coal></li>
            <li data-waste></li>
          </ul>
    

    here are my objects:

    const sbImpactTen = {
      miles: "3,418 less miles driven",
      coal: "1,524 less pounds of coal burned",
      waste: "60 trash bags of waste recycled"
    }
    
    const sbImpactFifty = {
      miles: "17,000 less miles driven",
      coal: "8,000 less pounds of coal burned",
      waste: "300 trash bags of waste recycled"
    }
    
    const sbImpactHundred = {
      miles: "34,000 less miles driven",
      coal: "15,000 less pounds of coal burned",
      waste: "3,596 trash bags of waste recycled"
    }
    

    and here is the function:

    var sbSlider = document.getElementById("location-range-slider");
    var output = document.getElementById("value");
    
    var cost = document.getElementById("monthly-cost");
    
    var impact = document.getElementById("impact-list");
    
    output.innerHTML = "10";
    
    sbSlider.oninput = function() {
      if (sbSlider.value === "1") {
        output.innerHTML = "10",
        cost.innerHTML = "$5",
        impact.innerHTML = sbImpactTen;
      } else if (sbSlider.value === "2") {
        output.innerHTML = "50",
        cost.innerHTML = "$20",
        impact.innerHTML = sbImpactFifty;
      } else {
        output.innerHTML = "100",
        cost.innerHTML = "$40",
        impact.innerHTML = sbImpactHundred;
      }
    }
    

    I am also including my codepen for viewing


  • Solution

  • Not sure about those other values, but for the HTML you show, just use querySelector and the data-attributes to target the elements

    let impact = document.querySelector("#impact-list")
    let slider = document.querySelector('.sbSlider');
    const sbImpactTen = {
      miles: "3,418 less miles driven",
      coal: "1,524 less pounds of coal burned",
      waste: "60 trash bags of waste recycled"
    }
    
    const sbImpactFifty = {
      miles: "17,000 less miles driven",
      coal: "8,000 less pounds of coal burned",
      waste: "300 trash bags of waste recycled"
    }
    const sbImpactHundred = {
      miles: "34,000 less miles driven",
      coal: "15,000 less pounds of coal burned",
      waste: "3,596 trash bags of waste recycled"
    }
    // listen to the changes 
    slider.addEventListener('input', e => adjustData(e.target))
    
    const adjustData = el => {
      let useImpact
      if (el.value === "1") {
        useImpact = sbImpactTen;
      } else if (el.value === "2") {
        useImpact = sbImpactFifty;
      } else {
        useImpact = sbImpactHundred;
      }
      for (let i in useImpact) {
        impact.querySelector(`li[data-${i}]`).innerHTML = useImpact[i]
      }
    }
    
    
    // kick it off with the default value
    adjustData(slider)
    <input type="range" min="1" max="3" value="1" class="sbSlider" id="myRange">
    <hr>
    <p>Equivelant impact to:</p>
    <ul id="impact-list">
      <li data-miles></li>
      <li data-coal></li>
      <li data-waste></li>
    </ul>