1

I'm new to JavaScript and I have made a list. You can add new items inn the list, you can delete the items from the list, also it has a little css for text decoration.

And I have a problem, I can't delete the new items from the list, I can only delete the old items from the list. If a add a new item, I can't delete it

This is the code:

var button = document.getElementById("enter");
var input = document.getElementById("userinput");
var ul = document.querySelector("ul");
var liEl = document.getElementsByTagName("li");
var btn = document.querySelectorAll("button");
var btnLength = btn.length;

function inputLength() {
    return input.value.length;
}

function createListElement() {
    var li = document.createElement("li");
    var delBtn = document.createElement("button");
    li.appendChild(document.createTextNode(input.value + " "));
    delBtn.appendChild(document.createTextNode("Delete"));
    ul.appendChild(li);
    li.appendChild(delBtn);
    btnLength++;
    btn[btnLength].addEventListener("click", clearItem);
    input.value = "";
}

function addListAfterClick() {
    if (inputLength() > 0) {
        createListElement();
    }
}

function addListAfterKeypress(theEvent) {
    if (inputLength() > 0 && theEvent.keyCode === 13) {
        createListElement();
    }
}

function changeClass() {
    this.classList.toggle("done");
}

function clearItem() {
    this.parentNode.remove();
}

button.addEventListener("click", addListAfterClick);

input.addEventListener("keypress", addListAfterKeypress);

eventChangeClass();

eventClearItem();

function eventChangeClass() {
    for (var i = 0; i < liEl.length; i++) {
    liEl[i].addEventListener("click", changeClass);
    }
}

function eventClearItem() {
    for (var i = 1; i < btnLength; i++) {
        btn[i].addEventListener("click", clearItem);
    }
}
.done {
    text-decoration: line-through;
}
<!DOCTYPE html>
<html>
<head>
    <title>JavaScript + DOM</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <h1>Shopping List</h1>
    <p id="first">Get it done today</p>
    <input id="userinput" type="text" placeholder="enter items">
    <button id="enter">Enter</button>
    <ul>
        <li class="bold red" random="23">Notebook <button>Delete</button></li>
        <li>Jello <button>Delete</button></li>
        <li>Spinach <button>Delete</button></li>
        <li>Rice <button>Delete</button></li>
        <li>Birthday Cake <button>Delete</button></li>
        <li>Candles <button>Delete</button></li>
    </ul>
    <script type="text/javascript" src="script.js"></script>
</body>
</html>

This is the error:

Uncaught TypeError: Cannot read property 'addEventListener' of undefined
at createListElement (script.js:20)
at HTMLButtonElement.addListAfterClick (script.js:26)
2
  • querySelectorAll is not a live collection of all buttons. Quick fix might be to use getElementsByTagName instead, which is a live collection, but it would be even better to use event delegation instead. Commented Aug 18, 2018 at 7:13
  • btn[btnLength] will always be undefined even with a live collection as there is no element at btnLength. Commented Aug 18, 2018 at 7:32

1 Answer 1

1

hey you placed some code in wrong place, btn = document.querySelectorAll("button"); btn[btnlength].addEventListener("click", clearItem);, I changed this to btn[btn.length].addEventListener("click", clearItem) you forget to take the new buttons, you only initialized btn on the page load, so each time you add new delete button, it is not added to the btn array. and you take btnlength only at the initial stage, so btn length varies. each time you need to reinit btn length. I have fixed and added a snippet. check that please.

var button = document.getElementById("enter");
var input = document.getElementById("userinput");
var ul = document.querySelector("ul");
var liEl = document.getElementsByTagName("li");
var btn = document.querySelectorAll("button");
var btnLength = btn.length;

function inputLength() {
    return input.value.length;
}

function createListElement() {
    var li = document.createElement("li");
    var delBtn = document.createElement("button");
    li.appendChild(document.createTextNode(input.value + " "));
    delBtn.appendChild(document.createTextNode("Delete"));
    ul.appendChild(li);
    li.appendChild(delBtn);
    btn = document.querySelectorAll("button");
    btnLength++;
   
    btn[btn.length -1].addEventListener("click", clearItem);
    input.value = "";
}

function addListAfterClick() {
    if (inputLength() > 0) {
        createListElement();
    }
}

function addListAfterKeypress(theEvent) {
    if (inputLength() > 0 && theEvent.keyCode === 13) {
        createListElement();
    }
}

function changeClass() {
    this.classList.toggle("done");
}

function clearItem() {
    this.parentNode.remove();
}

button.addEventListener("click", addListAfterClick);

input.addEventListener("keypress", addListAfterKeypress);

eventChangeClass();

eventClearItem();

function eventChangeClass() {
    for (var i = 0; i < liEl.length; i++) {
    liEl[i].addEventListener("click", changeClass);
    }
}

function eventClearItem() {
    for (var i = 1; i < btnLength; i++) {
        btn[i].addEventListener("click", clearItem);
    }
}
.done {
    text-decoration: line-through;
}
<!DOCTYPE html>
<html>
<head>
    <title>JavaScript + DOM</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <h1>Shopping List</h1>
    <p id="first">Get it done today</p>
    <input id="userinput" type="text" placeholder="enter items">
    <button id="enter">Enter</button>
    <ul>
        <li class="bold red" random="23">Notebook <button>Delete</button></li>
        <li>Jello <button>Delete</button></li>
        <li>Spinach <button>Delete</button></li>
        <li>Rice <button>Delete</button></li>
        <li>Birthday Cake <button>Delete</button></li>
        <li>Candles <button>Delete</button></li>
    </ul>
    <script type="text/javascript" src="script.js"></script>
</body>
</html>

Sign up to request clarification or add additional context in comments.

2 Comments

@RobGm I added description
Thank you Akhil. Now I understand my mistake, I just have the index of the new list item, but btn[btnLength] do not exist.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.