Home > Blockchain >  How to get elements inside NodeList
How to get elements inside NodeList

Time:09-22

I have a variable number of .row inside a #list div, the rows can be arranged with arrows up and down, if the row has no row above or below, the move arrow will deactivate.

I got the NodeList but when I try to change the button I get error unitsRows[i].getElementById is not a function

HTML

     <div id="List">
      <div id="listUnit0" class="row">
       <div class="text-center" style="width:50px;">
        <p>Name</p>
         </div>
        <button id="buttonMoveUnitDown" type="button" class="btn-custom mx-0">
         <i class="fas fa-arrow-down"></i>
        </button>
        <button id="buttonMoveUnitUp" type="button" class="btn-custom mx-0">
         <i class="fas fa-arrow-up"></i>
        </button>
       </div>
      </div>

      <div id="listUnit1" class="row">
       <div class="text-center" style="width:50px;">
        <p>Name</p>
         </div>
        <button id="buttonMoveUnitDown" type="button" class="btn-custom mx-0">
         <i class="fas fa-arrow-down"></i>
        </button>
        <button id="buttonMoveUnitUp" type="button" class="btn-custom mx-0">
         <i class="fas fa-arrow-up"></i>
        </button>
       </div>
      </div>
    </div>

JS

function checkMoveButtons(){
  var unitsRows = document.querySelectorAll("#list .row");
  console.log(unitsRows);

  for (var i = 0; i < unitsRows.length; i  ) {
    listUnitAbove = unitsRows[i].previousElementSibling;
    listUnitBelow = unitsRows[i].nextElementSibling;

    if (listUnitAbove === 'null'){
      unitsRows[i].getElementById('buttonMoveUnitUp').classList.add('btn-deactivate');
      unitsRows[i].getElementById('buttonMoveUnitUp').disabled = true;
    } else {
      unitsRows[i].getElementById('buttonMoveUnitUp').classList.remove('btn-deactivate');
      unitsRows[i].getElementById('buttonMoveUnitUp').disabled = false;
    }

    if (listUnitBelow === 'null'){
      unitsRows[i].getElementById('buttonMoveUnitDown').classList.add('btn-deactivate');
      unitsRows[i].getElementById('buttonMoveUnitDown').disabled = true;
    } else {
      unitsRows[i].getElementById('buttonMoveUnitUp').classList.remove('btn-deactivate');
      unitsRows[i].getElementById('buttonMoveUnitUp').disabled = false;
    }
  }
}

CodePudding user response:

ids must be unique. Use document.getElementById instead:

Your HTML is invalid, since you have duplicate ids. You should be using classes instead.

Your HTML should look like:

<div id="List">
  <div id="listUnit0" class="row">
    <div class="text-center" style="width:50px;">
      <p>Name</p>
    </div>
    <button type="button" class="btn-custom mx-0 buttonMoveUnitDown">
         <i class="fas fa-arrow-down"></i>
        </button>
    <button type="button" class="btn-custom mx-0 buttonMoveUnitUp">
         <i class="fas fa-arrow-up"></i>
        </button>
  </div>
</div>

<div id="listUnit1" class="row">
  <div class="text-center" style="width:50px;">
    <p>Name</p>
  </div>
  <button type="button" class="btn-custom mx-0 buttonMoveUnitDown">
         <i class="fas fa-arrow-down"></i>
        </button>
  <button type="button" class="btn-custom mx-0 buttonMoveUnitUp">
         <i class="fas fa-arrow-up"></i>
        </button>
</div>

And your function should be:

function checkMoveButtons(){
  var unitsRows = document.querySelectorAll("#list .row");
  console.log(unitsRows);

  for (var i = 0; i < unitsRows.length; i  ) {
    listUnitAbove = unitsRows[i].previousElementSibling;
    listUnitBelow = unitsRows[i].nextElementSibling;

    if (listUnitAbove === 'null'){
      unitsRows[i].querySelector('.buttonMoveUnitUp').classList.add('btn-deactivate');
      unitsRows[i].querySelector('.buttonMoveUnitUp').disabled = true;
    } else {
      unitsRows[i].querySelector('.buttonMoveUnitUp').classList.remove('btn-deactivate');
      unitsRows[i].querySelector('.buttonMoveUnitUp').disabled = false;
    }

    if (listUnitBelow === 'null'){
      unitsRows[i].querySelector('.buttonMoveUnitDown').classList.add('btn-deactivate');
      unitsRows[i].querySelector('.buttonMoveUnitDown').disabled = true;
    } else {
      unitsRows[i].querySelector('.buttonMoveUnitUp').classList.remove('btn-deactivate');
      unitsRows[i].querySelector('.buttonMoveUnitUp').disabled = false;
    }
  }
}

CodePudding user response:

Your html has repeated ID's of #buttonMoveUnitUp and #buttonMoveUnitDown. I changed them to be classes.

I also changed your for loop, into a forEach, since it's cleaner and easier to use.

Then I changed the repeated if / else statements into a function, so it's easier to see what it's doing.

function checkMoveButtons() {
  const unitRows = document.querySelectorAll("#list .row");

  unitRows.forEach((row) => {
    const up = row.previousElementSibling;
    const down = row.nextElementSibling;
    const btnMoveUp = up.querySelector(".buttonMoveUnitUp");
    const btnMoveDown = up.querySelector(".buttonMoveUnitDown");
    toggleBtn(up, btnMoveUp);
    toggleBtn(down, btnMoveDown)
  });
}

function toggleBtn(neighbour, btn) {
  if (!neighbour) {
    btn.classList.add("btn-deactivate");
    btn.disabled = true;
  } else {
    btn.classList.remove("btn-deactivate");
    btn.disabled = false;
  }
}

checkMoveButtons()
.btn-deactivate {
  color: grey;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" integrity="sha512-YWzhKL2whUzgiheMoBFwW8CKV4qpHQAEuvilg9FAn5VJUDwKZZxkJNuGM4XkWuk94WCrrwslk8yWNGmY1EduTA==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>

<div id="List">
  <div id="listUnit0" class="row">
    <div class="text-center" style="width:50px;">
      <p>Name</p>
    </div>
    <button type="button" class="buttonMoveUnitDown btn-custom mx-0">
      <i class="fas fa-arrow-down"></i>
    </button>
    <button type="button" class="buttonMoveUnitUp btn-custom mx-0">
      <i class="fas fa-arrow-up"></i>
    </button>
  </div>
</div>

<div id="listUnit1" class="row">
  <div class="text-center" style="width:50px;">
    <p>Name</p>
  </div>
  <button type="button" class="buttonMoveUnitDown btn-custom mx-0">
    <i class="fas fa-arrow-down"></i>
  </button>
  <button type="button" class="buttonMoveUnitUp btn-custom mx-0">
    <i class="fas fa-arrow-up"></i>
  </button>
</div>

  • Related