0

I can't figure out why the for loops won't iterate. I had them working at one point inside of the printInput function, but not outside. BTW, I'm still working on the code portion of the for both loops. One is supposed to close the object by removing it. The other is supposed to make the html element editable.

// close button
var closes = document.getElementsByClassName("closes");

for (var i = 0; i < closes.length; i++){
    closes[i].onclick = function (){
        var l = closes[i];
        l.remove();
    }
}

// edit button
var edit = document.getElementsByClassName("edit");

for(var i = 0; i < edit.length; i++){
    edit[i].onclick = function (){
        var x = this.parentElement;
        x.contentEditable = true;
    }
}



// Submits input by hitting enter
document.addEventListener("keyup", function(e) {
    if (e.keyCode === 13) {
        printInput();
    }
});



// Toggles checked class for finished chores
let selection = document.querySelector('ul');

selection.addEventListener("click", function(event) {
    if (event.target.tagName === 'LI') {
        event.target.classList.toggle('checked');
    }
}, false);

// This creates a new list object.
function printInput() {
    let input = document.getElementById('todotext').value;
        if (input === "" || null){
            alert("You haven't written anything!");
        } else {
            const newItem = document.createElement('li');
            const newNode = document.createTextNode(input);
            newItem.className  = "closes";
            newItem.appendChild(newNode);
            document.getElementById("list").appendChild(newItem);

            const img = document.createElement("img");
            img.src = 'edit.png'; 
            img.className = "edit";

            const newSpan = document.createElement("span");
            const xBtn = document.createTextNode("x"); 
            newSpan.className = "close";        
            newSpan.appendChild(xBtn);
            newItem.appendChild(img);
            newItem.appendChild(newSpan);
            
            document.getElementById("todotext").value = "";
           
    }
}
body {
    min-width: 850px;
    font-family: sans-serif;
    background-color: #ece0d9;
}

h1.title {
    width: auto;
    margin: auto;
    padding: 25px;
    text-align: center;
    -webkit-text-stroke: 1px #460a1e; /* width and color */
    font-family: sans-serif; color: white;
}

div.form {
    display: flex;
    padding: 10px;
    width: 50%;
    margin: auto;
    
}

input {
    width: 75%;
    padding: 10px 14px 11px 14px;
    margin: 0;
    border-radius: 0;
    border-width: thin;
    font-size: inherit;
    
}

input:focus {
    border-radius: 0;
    outline: none;
}

span.addTo {
    width: 25%;
    padding: 8px 14px 10px 14px;
    margin: 0;
    border-style: solid;
    border-width: thin;
    border-color: black;
    border-left: none;
    text-align: center;
    background-color: rgb(236, 235, 235);
}

span.addTo:hover {
    background-color: #e0e0e0;
    cursor: pointer;
}
 
ul.list{
    width: 50%;
    display: table;
    text-align: left;
    padding: 0;
    margin: auto;
}

ul.list li{
    padding: 10px 10px;
    background-color: snow;
    clear: right;
    margin: 0;
    position: relative;
    cursor: pointer;

}

ul.list li:nth-child(2n){
    background-color: rgb(240, 239, 239);

}

ul.list li.checked:nth-child(2n){
    text-decoration: line-through;

    background-color: rgb(170, 168, 168);

}

ul li.checked {
    text-decoration: line-through;
    background-color: rgb(170, 168, 168);
}

img.edit {
    position: absolute;
    right: 40px;
    top: 0;
    padding: 1px;
    width: 34px;
    height: 36.4px;
    cursor: pointer;
    background-color: transparent;
    color: rgb(75, 71, 71);

}

img.edit:hover {
    padding: 0;
    width: 34px;
    height: 36.4px;
    transition-property: background-color;
    transition-duration: .3s;
    border-style: ridge;
    border-color: black;
    border-width: 1px;
}

span.close {
    position: absolute;
    right: 0;
    top: 0;
    padding: 10px 14px 10px 14px;
    cursor: pointer;
    background-color: transparent;
    color: rgb(75, 71, 71);

}



span.close:hover {
    color: black;
    padding: 9px 13px 9px 13px;
    transition-property: background-color;
    transition-duration: .3s;
    border-style: ridge;
    border-color: black;
    border-width: 1px;
}
<!DOCTYPE html>
<html>
    <head>
        <title>To-Do List</title>
        <meta charset="en">
        <link rel="stylesheet" href="main.css">
    </head>
    <body>
        <h1 class="title">To-Do List</h1>
        
            <div class="form">
                
                    <input type="text" id="todotext">
                    <span  onclick="printInput()" id="addTo" class="addTo">Add</span>
                
            </div>
        
            <ul style="list-style-type:none;" class="list" id="list">
            <li hidden id="close">Clean room<img src="edit.png" class="edit"><span class="close">x</span></li>

            </ul>

                <script src="main.js">
                </script>
        
    </body>
</html>
Bishibro
  • 23
  • 5
  • Your "edit" button should be working, but your "close" button doesn't work because by the time the click occurs, `i` is too high and so `closes[i]` is `undefined`. This is because you've used `var`. If you used `let`, it should work (see the linked question's answers), but better to use `this` to refer to the button (or accept the event object and use `event.currentTarget`) instead of `closes[i]`. Also, best practice is to use [`addEventListener`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) rather than assigning to `onclick`. – T.J. Crowder Jan 28 '22 at 17:37
  • 1
    @T.J.Crowder - IMO the bigger issue here is event delegation - whereas your duplicate link is all about for loops (which may also be helpful). However even with polishing those up, OP will still fail on dynamically created todo list items. – Kinglish Jan 28 '22 at 17:49
  • @bishibro. You need to use event delegation for the close and edit links - since those are being created dynamically – Kinglish Jan 28 '22 at 17:51
  • @Kinglish - Good point, I missed that part. I've added the [canonical dupe](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) for that to the list. Thanks for calling it out! – T.J. Crowder Jan 28 '22 at 17:59
  • @Kinglish Thank you! – Bishibro Jan 28 '22 at 18:10

0 Answers0