Roman Baron
Roman Baron

Reputation: 45

Why is my javascript code duplicating li?

I am a Javascript beginner (this is my first javascript program) and I have a few problems with my mini app...

I am trying to build a page that allows you to choose who was in your team working with you today. The user should be able to build his own list among a list of names.

When the user clicks on "Add to the team", it should remove the corresponding <li> and add it to the selected list below.

The button needs to change from Add to the team to Delete

I am struggling to change the button textcontent if user choose to add then remove then add the same <li>...

I've been trying a lot of things, this is my last try:

'script type="text/javascript"';

    var selected = document.querySelector('#selected-list ul');
    var team = document.querySelector('#team-list ul');
    var searchBar = document.forms['search-employees'].querySelector('input');

//add to the selected team
 team.addEventListener("click", function(e){
	if(e.target.className == 'add'){
        
        const li = document.createElement('li');
        const employeename = document.createElement('span');
        const deleteBtn = document.createElement('span');
    
        //add content
        deleteBtn.textContent = 'add';
        employeename.textContent = e.target.parentElement.firstElementChild.textContent;
        
        //add classes
        employeename.classList.add("name");
        deleteBtn.classList.add('delete');
    
        // append to document
        li.appendChild(employeename);
        li.appendChild(deleteBtn);
        selected.appendChild(li);  
        console.log(deleteBtn);
    }
})
	
//delete teammate from selected team
selected.addEventListener('click', function(e){    

    if(e.target.className == 'delete'){
        const li = document.createElement('li');
        const employeename = document.createElement('span');
        const addBtn = document.createElement('span');
    
        //add content
        addBtn.textContent = 'delete';
        employeename.textContent = e.target.parentElement.firstElementChild.textContent;
	
        //add classes
        employeename.classList.add("name");
        addBtn.classList.add('add');
    
        // append to document
        li.appendChild(employeename);
        li.appendChild(addBtn);
        team.appendChild(li);  
        //delete from selected
        console.log(addBtn);
    }				
})
//add a new employee - listen to submit event from form
var addForm = document.forms['add-employee'];

addForm.addEventListener('submit', function(e){
	e.preventDefault(); //prevent default behavior
	const value = addForm.querySelector('input[type="text"]').value;
    console.log(value);
		
	//create elements
	const li = document.createElement('li');
	const employeename = document.createElement('span');
	const deleteBtn = document.createElement('span');
    
	//add content
	deleteBtn.textContent = 'delete';
	employeename.textContent = value;
	
    //add classes
    employeename.classList.add("name");
    deleteBtn.classList.add('delete');
    
	// append to document
	li.appendChild(employeename);
	li.appendChild(deleteBtn);
	selected.appendChild(li);  
    
    //apply style
    
})


//filter names
//grab a reference to the form

searchBar.addEventListener('keyup', function(e){
    //term the user is searching
    const term = e.target.value.toLowerCase();
    //names to compare
    const names = team.getElementsByTagName('li');

    Array.from(names).forEach(function(name){
        const fullname = team.firstElementChild.textContent;
        //check if name exists
        if(fullname.toLowerCase().indexOf(term) != -1){
            name.style.display = 'block';
        } else {
            name.style.display = 'none';
        }
    
    })
                           
})

It gives me the following result: Every time I hit the button, it gives me a duplicate (same for the input Teammate not found) Moreover, I still can't, once deleted, get back to a "Add to the team"...

I hope you guys can enlighten me, I spent maybe too much time on it, but I cant find out right now...

This is few captions of what it does: enter image description here

once you clicked on delete in selected list enter image description here

Thank you HTML:

<?php 
	require_once 'core/init.php';	
	include 'includes/checkedboxes.php';
	include 'includes/headerfront.php';
	//include_once 'includes/dbh.inc.php';
	if(Session::exists('Success')){	
		echo Session::flash('Success');
	}
?>
<html>

<head>
  <link rel="stylesheet" href="styleChief.css">

</head>

<body>
  <section class="team">
    <div id="wrapper">
      <div id="container-left">
        <div id="search">
          <h2 class="title">Who was in your team today?</h1>
            <form id="search-employees">
              <input type="text" name="search" placeholder="Search a name..">
            </form>
        </div>

        <div id="team-list">
          <h3 class="title">Team list</h3>
          <p>Select today's teammates</p>
          <ul>
            <li>
              <span class="name">name</span>
              <span class="add">Add to the team</span>
            </li>
            <li>
              <span class="name">name 1</span>
              <span class="add">Add to the team</span>
            </li>
            <li>
              <span class="name">name 2</span>
              <span class="add">Add to the team</span>
            </li>
            <li>
              <span class="name">name 3</span>
              <span class="add">Add to the team</span>
            </li>
          </ul>
        </div>

        <div id=newmember class="newmember">
          <h4>
            <a class="not-found" href="#"><img class="img" src="img/not-found.png" width="20" height="20" alt="not-found">
            </a>Teammate not found?</h4>
          <form id="add-employee">

            <h3 class="title">Add a new member:</h3>
            <input type="text" placeholder="New teammate name">
            <button>Add</button>

          </form>
        </div>
      </div>

      <div id="container-right">
        <h2>Selected</h2>
        <div id="selected-list">
          <h3 class="title">You have selected the following teammates for today: </h3>
          <ul>

          </ul>
        </div>
      </div>
    </div>
  </section>

  <section class="part">

    <h2>Which part(s) have you been working on today?</h2>
    <input type="checkbox" name="checklist-part" value="Decoratives"><label>Decoratives</label>
    <input type="checkbox" name="checklist-part" value="Windows"><label>Windows</label>
    <input type="checkbox" name="checklist-part" value="Signage Gibela"><label>Signage Gibela</label>
    <input type="checkbox" name="checklist-part" value="Signage Prasa"><label>Signage Prasa</label>
    <input type="checkbox" name="checklist-part" value="Stripes"><label>Stripes</label>
    <input type="checkbox" name="checklist-part" value="Other"><label>Other</label><br/>
    <input type="submit" name="submit" value="Continue" /><br/>

    </form>

  </section>
  <?php
			$sql="SELECT * FROM dttechnames;";
			$result=mysqli_query($conn,$sql);

		?>

    <script src="app/app.js"></script>
    <script src="app/app.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</body>

</html>

Upvotes: 1

Views: 108

Answers (2)

Roman Baron
Roman Baron

Reputation: 45

After trying cars10m solution, I have few problems..

1. The css style of my "Add to the team" disappeared. I of course changed my code above to:

.add,.delete {
    float: right;
    background: #9361bf;
    padding:6px;
    border-radius: 4px;
}

to :

.move{
    float: right;
    background: #9361bf;
    padding:6px;
    border-radius: 4px;
}

but doesnt style the class. Maybe move is a reserved keyword?

Anyways, I have another problem:

2. That solution moves the selected "li", but inside the same <ul>.

When I do a console.log(e.target.textContent) just after if(e.target.classList.contains('move')), i get to see that it contains "Add to the team" and "Remove from the team".

I found out that it was behaving as if I clicked two twice, but I only clicked once.

Why?

Thank you guys for your answers!!

Upvotes: 0

Carsten Massmann
Carsten Massmann

Reputation: 28206

I tried to fx a few issues with your snippet (e. g. there was a <form> tag missing). Basically, you were working far too hard in your script part. If you want to move a <li> from one <ul> to another then it is easiest to simply .appendChild() it to the target <ul>. Doing so will automatically remove it from its original parent <ul>. As the "move" operation is universal to all team-member-<li>s - whether they are part of the "team" or the "selected" group - we can use a single "click" event-listener for all of them. I added it to the outer #wrapper div.

The following snippet only covers the team member picking part (I removed all other script components for clarity) but it should demonstrate the basic points:

var grps=['#selected','#team'].map(s=>document.querySelector(s+'-list ul')),
    btn=['Add to the team','Remove from the team'];    
[...grps[1].querySelectorAll('.move')].forEach(sp=>sp.textContent=btn[0])

// move members ...
document.querySelector('#wrapper').addEventListener("click", function(e){
  if(e.target.classList.contains('move')){
    var i=btn.indexOf(e.target.textContent); // i=0 (Adding)  or  i=1 (Removing) ?
    e.target.textContent=btn[1-i];           // exchange button caption
    grps[i].appendChild(e.target.parentNode) // move team member ...
  }
})
li {margin: 10px}
.move{
    float: right;
    background: #9361bf;
    padding:4px;
    border-radius: 3px;
}
<section class="team">
    <div id="wrapper">
      <div id="container-left">
        <div id="search">
          <h2 class="title">Who was in your team today?</h1>
            <form id="search-employees">
              <input type="text" name="search" placeholder="Search a name..">
            </form>
        </div>

        <div id="team-list">
          <h3 class="title">Team list</h3>
          <p>Select today's teammates</p>
          <ul>
            <li>
              <span class="name">Roman BARON</span>
              <span class="move"></span>
            </li>
            <li>
              <span class="name">Vincent Houdeville</span>
              <span class="move"></span>
            </li>
            <li>
              <span class="name">Jayson Abrams</span>
              <span class="move"></span>
            </li>
            <li>
              <span class="name">Bafana Hlongwane</span>
              <span class="move"></span>
            </li>
          </ul>
        </div>

        <div id=newmember class="newmember">
          <h4>
            <a class="not-found" href="#"><img class="img" src="img/not-found.png" width="20" height="20" alt="not-found">
            </a>Teammate not found?</h4>
          <form id="add-employee">

            <h3 class="title">Add a new member:</h3>
            <input type="text" placeholder="New teammate name">
            <button>Add</button>

          </form>
        </div>
      </div>

      <div id="container-right">
        <h2>Selected</h2>
        <div id="selected-list">
          <h3 class="title">You have selected the following teammates for today: </h3>
          <ul>

          </ul>
        </div>
      </div>
    </div>
  </section>

  <section class="part">

    <h2>Which part(s) have you been working on today?</h2>
    <form id="parts">
    <label><input type="checkbox" name="checklist-part" value="Decoratives">Decoratives</label>
    <label><input type="checkbox" name="checklist-part" value="Windows">Windows</label>
    <label><input type="checkbox" name="checklist-part" value="Signage Gibela">Signage Gibela</label>
    <label><input type="checkbox" name="checklist-part" value="Signage Prasa">Signage Prasa</label>
    <label><input type="checkbox" name="checklist-part" value="Stripes">Stripes</label>
    <label><input type="checkbox" name="checklist-part" value="Other">Other</label><br/>
    <input type="submit" name="submit" value="Continue" /><br/>

    </form>

  </section>

This seems to have been the first question you posted on StackOverflow, so a belated: "Welcome here!"

But I would like to point out that your question was unnecessarily long and complicated. You should try and focus on one point per question. This would make it much more accessible for other Stackoverflow members to answer without having to review large chunks of code first.

And one final remark: You tagged your question with jQuery, but as you haven't used it in your script I also removed the script src="...jquery..."></script> tag from my snippet. I am eternally grateful to John Resig for giving us jQuery but in modern browsers you can now mostly do without it.

Upvotes: 1

Related Questions