# To do Liste



## MarcMarc (20. Feb 2022)

Einen schönen guten Abend an alle. Ich komme mir momentan ziemlich doof vor, weil ich gerade hobbymäßig an einer to do Liste in JavaScript arbeite. Soweit hat bis jetzt alles funktioniert. Wenn ich was in das "input feld" mit der id "to do field" eingebe, erscheint unten das eingegebene in der "ul" und wenn ich diese über die Checkbox anklicke wird der eingegebene Text durchgestrichen. Nur wenn ich auf das "close" Icon drücke verschwindet das Feld nicht. ich habe schon mehrere Sachen probiert aber nichts will so recht klappen. Über eure Hilfe oder Anmerkungen wie man das (definitiv) besser schreiben könnte bin ich euch sehr dankbar!

mit freundlichen Grüßen

Marc

[CODE lang="javascript" title="javascript"]var toDoList = document.querySelector('#toDoList');
var content = document.getElementsByClassName('checkContainer');
var i;


function addTodo() {

    toDoList.innerHTML +=
`<div class="checkContainer">

  <input class="check1" type="checkbox">
  <span class="toDoText">${toDoField.value}</span>
  <i class="close">\u00D7</i>

</div> `;

    toDoField.value = '';

    for (i = 0; i < content.length; i++) {}

}

var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
  close_.onclick = function () {

    content.style.display = "none";
  }
}[/CODE]


		HTML:In die Zwischenablage kopieren


    <div class="page-content">

        <form onsubmit="addTodo(); return false;" autocomplete="off" id="myform">

            <div class="input-field">

                <input type="text" required id="toDoField">
                <label for="toDoField"></label>
                <span class="placeholder">To do einfügen</span>

            </div>

            <button type="submit">
                SPEICHERN
            </button>

        </form>

    <div class="list">

        <h2>Check List</h2>

        <ul id="toDoList"></ul>

     
    </ul>

    </div>

    </div>

_


----------



## Oneixee5 (21. Feb 2022)

Du erstellst beim Öffnen der Seite ein Array:
var close = document.getElementsByClassName("close");
und jedem Element des Arrays fügst du den onclick-Listener hinzu.
Den neu erstellten Listeneinträgen (welche nicht zum Array gehören) fügst du aber keinen onclick-Listener hinzu. Deshalb reagieren diese nicht auf onclick.


----------



## MarcMarc (21. Feb 2022)

Danke für den Hinweis! Also muss ich mir ein "Werkzeug" heraus suchen, welches auch die neu erstellten Listeneinträgen zum Array hinzufügt oder ist der gesamte Ansatz den ich gewählt habe schon Käse und alles für die Tonne?
Haben Sie vielleicht eine Quelle oder Tipp für mich. Wo ich mehr über genau diese Thematik lernen kann? 

Großes Dankeschön


----------



## Oneixee5 (22. Feb 2022)

Dem Array musst du das neue Element nicht hinzufügen. Ich glaube das wäre nutzlos. Ich denke du müsstest die Funktion anpassen.
So in der Art:

```
function addTodo() {
var div = document.createElement('div');
// add class checkContainer to div
div.innerHTML = "div inner html code";
div.getElementsByClassName('close').addEventListener("click", function() {
    // code to remove the div
});
toDoList.appendChild(div);
}
```
Keine Ahnung ob das so funktioniert aber ich hoffe das Prinzip ist zu erkennen.


----------



## MarcMarc (22. Feb 2022)

Ich habe es jetzt geschafft und mich von deinem Prinzip motivieren lassen, leider musste ich dafür schummeln und habe mir viele Zeilen von "https://www.w3schools.com/howto/howto_js_todolist.asp" rauskopiert. Im großen und ganzen verstehe ich das ganze. Elemente in JS kreieren, diesen Klassen zuweisen und mit appendChild an die jeweiligen Elemente als Kindelement anhängen. Mit der for Schleife kriegen "myNodeList und "close" für jede Erstellung einen steigenden index durch "i" zugewiesen, um dadurch jedes einzelne listen/close element ansprechen zu können. Korrigiere mich falls ich da schon falsch liege. Was ich aber noch nicht verstehe ist warum ich das onclick Event zweimal brauche Zeile 13-20 und nochmal in Zeile 45-51. dann verstehe ich noch nicht in zeile 17-18/47-48 worauf sich this.parentElement bezieht.  Als letztes frage ich mich, warum ich den "
// Create a "close" button and append it to each list item" Teil in Zeile 2-10, nicht in die "AddTodo()" Funktion reinmachen kann.

```
// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
  var span = document.createElement("SPAN");
  var txt = document.createTextNode("\u00D7");
  span.className = "close";
  span.appendChild(txt);
  myNodelist[i].appendChild(span);
}

// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
  close[i].onclick = function () {
    var div = this.parentElement;
    div.style.display = "none";
  }
}


// Create a new list item when clicking on the "Add" button
function addTodo() {
  var li = document.createElement("li");
  var input = document.createElement("INPUT");
  input.setAttribute("type", "checkbox");
  li.appendChild(input);
  var inputValue = document.getElementById("toDoField").value;
  var toDoText = document.createElement('P')
  toDoText.className = "toDoText";
  toDoText.innerHTML = inputValue;
  li.appendChild(toDoText);

  document.getElementById("toDoList").appendChild(li);
 
  document.getElementById("toDoField").value = "";

  var span = document.createElement("SPAN");
  var txt = document.createTextNode("\u00D7");
  span.className = "close";
  span.appendChild(txt);
  li.appendChild(span);

  for (i = 0; i < close.length; i++) {
    close[i].onclick = function () {
      var div = this.parentElement;
      div.style.display = "none";
    }
  }
}
```


----------



## Oneixee5 (22. Feb 2022)

Ich denke die for-Schleife in addTodo brauchst du gar nicht, Zeile 45-51. Du solltest das so machen, wie ich oben angedeutet habe, nur für das neue Element den Listener hinzufügen.
this ist das Element an welches die Funktion gebunden ist, this.parentElement ist dann das übergeordnete Element von this.
Solche DOM-Abfragen solltest du nicht wiederholen: document.getElementById("toDoList"), das macht deine Seite sehr langsam. Merke dir das einfach als Variable.


----------



## MarcMarc (22. Feb 2022)

Ich habe die for Schleife in addTodo weggelassen, dann kann ich aber nur den ersten Eintrag wieder entfernen, die darauffolgenden reagieren dann nicht mehr, wenn ich auf das close icon klicke. 
Die dom abfragen habe habe ich jetzt schon vor addTodo als var deklariert, die ich in addTodo jetzt statt der Dom Abfrage verwende. Also meinst du das es besser ist wenn ich das onclick Event durch dein Listener ersetze? Quasi so:

```
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
  var span = document.createElement("SPAN");
  var txt = document.createTextNode("\u00D7");
  span.className = "close";
  span.appendChild(txt);
  myNodelist[i].appendChild(span);
}



var toDoList = document.getElementById("toDoList");
var toDoField = document.getElementById("toDoField");


// Create a new list item when clicking on the "Add" button
function addTodo() {
  var li = document.createElement("li");
  var input = document.createElement("INPUT");
  input.setAttribute("type", "checkbox");
  li.appendChild(input);
  var inputValue = document.getElementById("toDoField").value;
  var toDoText = document.createElement('P')
  toDoText.className = "toDoText";
  toDoText.innerHTML = inputValue;
  li.appendChild(toDoText);

  toDoList.appendChild(li);
 
  toDoField.value = "";

  var span = document.createElement("SPAN");
  var txt = document.createTextNode("\u00D7");
  span.className = "close";
  span.appendChild(txt);
  li.appendChild(span);

span.getElementsByClassName('close').addEventListener("click", function() {
  var div = this.parentElement;
      div.style.display = "none";
}); 
    }
  }
}
```


----------



## Oneixee5 (22. Feb 2022)

Ich habe das hier https://jsfiddle.net/x3vzoufL/29/ mal getestet. Ich denke so ist es etwas kompakter und leichter verständlich


----------



## MarcMarc (22. Feb 2022)

Wow! Das ist sogar noch besser und verständlicher für mich, besten Dank! Wie läuft das denn in Zeile 14 mit "  const close = div.getElementsByClassName('close')[0];" sagt das aus, dass im jeden neu erstellten checkContainer das nullte close Element angesprochen wird oder wie steht der Bezug vom close Ellement zum dazugehörigen checkConatiner?


----------



## Oneixee5 (22. Feb 2022)

Die Funktion getElementsByClassName gibt ein. Array zurück und 0 ist der Index des ersten Elements. div ist das Element, welches durchsucht wird.


----------

