1

I am trying to create a simple phone book in javascript. I want when the user clicks on "Add Contact" to have their name and phone appear in a separate division at the bottom. I have the code below, but for some reason it's not working. What are your thoughts?

var persons = {};
function showTable() {
  str = "";
  for (var i = 0; i < persons.length; i++) {
    str += `<tr>
              <td>${persons[i].name}</td>
              <td>${persons[i].phone}</td>
            </tr>`
  }
  document.querySelector("table tbody").innerHTML = str;
}
<!DOCTYPE html>
<html>

<head>
  <title>PhoneBook</title>
</head>

<body>
  <h1>PhoneBook</h1>
  <form>
    <label for="name">Name</label>
    <input type="text" name="name" id="name">
    <label for="phone">Phone</label>
    <input type="text" name="phone" id="phone">
    <input type="button" class="btn" value="Add contact" onclick="showTable;">
  </form>
  <div id="containerPhoneBook">
    <table id="inputs">
      <thead>
        <tr>
          <td>Name</td>
          <td>Phone</td>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
  </div>
</body>

</html>

2
  • 5
    You onclick should be onclick="showTable()". Also, you are not getting the text from the input boxes anywhere in your code Commented Nov 18, 2018 at 7:45
  • Hi Nick, thanks! I see now my mistake showTable(). What I don't understand is...why should I get the text from the input boxes and where? I already defined the user value for name and phone in the for loop and stated that I wanted it in the table. Many thanks in advance! Commented Nov 18, 2018 at 7:52

2 Answers 2

1
  1. You define an empty object. You need an array [] and you can pre-populate it or not. A prepopulated array would look like
    var persons = [{ name:"Fred", phone:" 123"}, {name:"Bob", phone:"234"}];
  2. You need to call the function using () as in showTable()
  3. You did not store the persons on click of add so I created an addTable that calls showTable each time

var persons = [];

function showTable() {
  str = "";
  for (var i = 0; i < persons.length; i++) {
    str += `<tr>
              <td>${persons[i].name}</td>
              <td>${persons[i].phone}</td>
            </tr>`
  }
  document.querySelector("table tbody").innerHTML = str;
}

function addTable() {
  persons.push({
    name: document.getElementById("name").value,
    phone: document.getElementById("phone").value
  })
  showTable();
}
window.addEventListener("load", showTable);
<!DOCTYPE html>
<html>

<head>
  <title>PhoneBook</title>
</head>

<body>
  <h1>PhoneBook</h1>
  <form>
    <label for="name">Name</label>
    <input type="text" name="name" id="name">
    <label for="phone">Phone</label>
    <input type="text" name="phone" id="phone">
    <input type="button" class="btn" value="Add contact" onclick="addTable();">
  </form>
  <div id="containerPhoneBook">
    <table id="inputs">
      <thead>
        <tr>
          <td>Name</td>
          <td>Phone</td>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
  </div>
</body>

</html>

You see I use an event handler to wait for the table to exist. It is not recommended to use inline event handlers so you could also do document.querySelector(".btn").addEventListener("click",addTable)

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

4 Comments

Thank you very much! I am trying out your version. Before adding any contact, I want the list to be empty - so no Fred or Bob. My question is how to define an empty object? Is this correct: var persons = {}; ?
@Ioana {} is not correct, because persons will contain more than one person, so you need persons to be array (as you can see in my answer)
@Ioana No, just empty my array: var persons = []; - you do need an array to have multiple persons
@mplungjan Thank you very much for your helpful solution. It is exactly what I needed!
0

You must append new persons to persons. I created a new function addPerson for this purpose.

JS

 var persons = [];
 function addPerson(name,phone){
   person={
     name:name.substring(0),
     phone:phone.substring(0)
   }
   persons.push(person)
   showTable()
 }
 function showTable() { 
   str = ""; 
   for (person of persons) {
     str += '<tr>
       <td>'+person.name+'</td>
       <td>'+person.phone+'</td>
     </tr>'
   }
   document.querySelector("table tbody").innerHTML = str;
 }

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>PhoneBook</title>
  </head>
  <body>
    <h1>PhoneBook</h1>
    <form>
      <label for="name">Name</label>
      <input type="text" name="name" id="name">
      <label for="phone">Phone</label>
      <input type="text" name="phone" id="phone">
      <input type="button" class="btn" value="Add contact" onclick="addPerson(document.getElementById('name').value,document.getElementById('phone').value)">
    </form>
    <div id="containerPhoneBook">
      <table id="inputs">
        <thead>
          <tr>
            <td>Name</td>
            <td>Phone</td>
          </tr>
        </thead>
        <tbody>
        </tbody>
      </table>
    </div>
  </body> 
</html>

1 Comment

It is not recommended to have inline even handlers and unnecessary to pass anything in the call. For a better solution see my answer

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.