I set up a webpage with two headings, and two buttons. The webpage looks exactly like the following before pressing on anything:
Counter-1 : (somenumber)
[Increment Button] || [Decrement Nutton]
If I click on the first button, the somenumber increments by 1. If I click on the second button, the somenumber decrements by 1.
In addition, when I click on the first button(increment-button), a list-item gets added to the webpage. When I click on the second button(decrement-button), the last added list-item gets removed from the webpage.
Both buttons work and do their purpose (incrementing/decremnting wise), and when I click on the first button, a list-item indeed gets added to the webpage.
The problem occurs when I try to remove the last added list item, by pressing the second button, as described.
This is the html section. Nothing out of the ordinary. One heading, and two buttons.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>Counter-1: <span id="counter-one">0</span></h1>
<button id="increment">Increment Number</button>
<button id="decrement">Decrement Number</button>
<ul id="list-items"></ul>
<script src="script.js" type="text/javascript"></script>
</body>
</html>
This is the JavaScript section. I get the two buttons from the HTML document, I set up an empty list on the HTML document, which I wanted to fill with one list-item per click on the first button (using javascript, hence making the button interactive).
const incrementButton = document.getElementById("increment");
const decrementButton = document.getElementById("decrement");
const listOfItems = document.getElementById("list-items");
const counterValue = document.getElementById("counter-one");
let counter = 0;
function incrementValue() {
counter++;
counterValue.innerText = counter;
//add a list item
const li = document.createElement("li");
li.innerHTML = "<b>Something</b> " + counter;
li.setAttribute("data-counter", counter);
listOfItems.appendChild(li);
console.log(li);
}
function decrementValue() {
counter--;
counterValue.innerText = counter;
//remove a list item
const li = listOfItems.querySelector("[data-counter = " + counter + "]");
li.remove();
}
incrementButton.addEventListener("click", incrementValue);
decrementButton.addEventListener("click", decrementValue);
The mechanism of incrementing and decrementing the value is working properly, and the appending of the list-items works as well, as mentioned.
But the lines:
listOfItems.querySelector("[data-counter = " + counter + "]");
li.remove();
used to "catch" the last added list-item,
are causing the following error:
Uncaught DOMException: Failed to execute 'querySelector' on 'Element': '[data-counter = 1]' is not a valid selector. at HTMLButtonElement.decrementValue
And I don't understand why the querySelector is invalid. I am certain that I have written something incorrect, or perhaps, an obsolete statement. How can I fix it?
The counter
should be wrapped in quotes (and no blank spaces!) when used in data attribute selector. Use instead Template Literals:
ulElement.querySelector(`[data-counter="${counter}"]`);
or, if you insist in double quotes escape them with backslash like:
ulElement.querySelector("[data-counter=\""+ counter +"\"]");
or, use single quotes to preserve double quotes like:
ulElement.querySelector('[data-counter="'+ counter +'"]');