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:
id
s must be unique. Use document.getElementById
instead:
Your HTML is invalid, since you have duplicate id
s. 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>