Search code examples
javascriptfunctionappendchild

How can I move the created content of a <div1> into a <div2> without moving the whole <div1> and keep creating elements in <div1>?


I'm trying to code a to do list with vanilla JS/Html in which elements from "To Do" can end up in "Done" when clicked. I have made my icons clickable, I have managed to move content from one div to the other, but I have several issues and I can't seem to find the problem lies:

1: Why does my JS script move my whole 'doList' div into my 'doneList' div when I (thought I) asked for it to move the <li id=todotask> only? is it a parent problem? (line 24)

2: How do I manage to move only ONE <li> element, the one I click, and not the others? Right now they all get the same ID upon appearing so I guess that's going to be a problem, so...

3: Is there a way I can give every <li> a different ID and change the moved <li> element's ID after I click it?

4: When I finally get my <li> element in the right div after click, how can I "restart" my function so the next <li> element I put in my input appears in "todo" and not in "done" after the one I moved?

Here is what I've read and tried so far : changing the parent and the child in my moveItem function, give an ID to my <li> elements upon creation, removing and adding an ID using li.id and classList.remove/add, read at least 50 SO answers on how to move divs into one another but didn't find anything that would fit my need, since I want to move a .createElement created <li> onclick and be done with it, not have a div move by itself, move elemenets that are already in my html or fuse content of two divs...

Here is my JS code:

function newItem() {
  console.log("Inside newItem")

  //set variables
  let item = document.getElementById("taskinput").value;
  let ul = document.getElementById('doList');
  let li = document.createElement('li');
  li.id = 'todotask';

// now put text in list item
  li.appendChild(document.createTextNode(item));
  ul.appendChild(li); // put list item in our unordered list
  document.getElementById("taskinput").value = ""; // erase what is currently in todo
  li.onclick = moveItem; // run moveItem when the li is clicked
}

function moveItem(e) {
  var moveTo = this.parentElement.parentElement == doneList ? todotask : doneList;
  moveTo.appendChild(this.parentElement);
  console.log("Item Moved to Done")
}

document.body.onkeyup = function(e) {

  let item = document.getElementById("taskinput").value;
  if (e.keyCode == 13) {
    console.log('enter pressed!');
    newItem();
    console.log(item);
  };
};

document.getElementById('addtask').onclick = function() {
  console.log('Add button pressed!')
  newItem()
}
<body>

  <div class="container">
    <div>
      <h1>To Do List</h1>
    </div>

    <div id="addtaskbar">
      <input type="text" name="taskinput" id="taskinput" placeholder="What do you have to do next?">
      <input type="button" name="addtask" id="addtask" value="Add">
    </div>
  </div>
  <div class="container">
    <div id="todo">
      <ul id='doList'>

      </ul>
    </div>

    <div id="done">
      <ul id='doneList'>

      </ul>

    </div>
  </div>

here is what it shows on my inspector before and after I move my elements:

Before:

1

After:

2


Solution

  • In moveItem, this is the ul. So you should be moving this, not this.parentElement.

    Also, doList or doneList will be the parent of the element, not the grandparent, so you need to change the condition in the ternary expression.

    And the destination when moving back should be doList, todotask is the ID of a specific task. You also shouldn't create duplicate IDs like that. There's no need to give an ID to the tasks that are created dynamically.

    function newItem() {
      console.log("Inside newItem")
    
      //set variables
      let item = document.getElementById("taskinput").value;
      let ul = document.getElementById('doList');
      let li = document.createElement('li');
    
      // now put text in list item
      li.appendChild(document.createTextNode(item));
      ul.appendChild(li); // put list item in our unordered list
      document.getElementById("taskinput").value = ""; // erase what is currently in todo
      li.onclick = moveItem; // run moveItem when the li is clicked
    }
    
    function moveItem(e) {
      var moveTo = this.parentElement == doneList ? doList : doneList;
      moveTo.appendChild(this);
      console.log("Item Moved to " + (moveTo == doneList ? "Done" : "ToDo"))
    }
    
    document.body.onkeyup = function(e) {
    
      let item = document.getElementById("taskinput").value;
      if (e.keyCode == 13) {
        console.log('enter pressed!');
        newItem();
        console.log(item);
      };
    };
    
    document.getElementById('addtask').onclick = function() {
      console.log('Add button pressed!')
      newItem()
    }
    <body>
    
      <div class="container">
        <div>
          <h1>To Do List</h1>
        </div>
    
        <div id="addtaskbar">
          <input type="text" name="taskinput" id="taskinput" placeholder="What do you have to do next?">
          <input type="button" name="addtask" id="addtask" value="Add">
        </div>
      </div>
      <div class="container">
        To Do
        <div id="todo">
          <ul id='doList'>
    
          </ul>
        </div>
        Done:
        <div id="done">
          <ul id='doneList'>
    
          </ul>
    
        </div>
      </div>