onlyforbopi
9/27/2018 - 8:46 AM

JS.Template.CourseProject

JS.Template.CourseProject

body {
  background: URL('https://www.toptal.com/designers/subtlepatterns/patterns/circles-dark.png');
}


#contactsDiv {
  padding: 2px;
}

form {
  width: 550px;
}

#name, #email {
  width: 180px;
	padding: 2px;
	margin: 2px;	  
}

#searchField, #searchFieldLabel {
	padding: 2px;
	margin: 15px 0px;	    
}

button {
	padding: 3px;
	margin: 5px;	
    background-color: black;
    color: white;
    cursor: pointer;
    border-radius: 8px;
}

button:hover {
	box-shadow: 0 0 6px rgba(35, 173, 278, 1);	
}

table {
  border-top: 20px;
  border: 1px black solid;
  padding: 6px;
}

th {
  border-bottom: 1px black solid;  
}

tr, th, td {
  padding: 4px;
}
class Contact {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }
  
  equals(other) {
    if (this.name === other.name &&
        this.email === other.email) {
      return true;
    }
    return false;
  }
  
  printContactToConsole() {
    console.log('Name: ' + this.name + ' Email: ' + this.email);
  }
  
  searchContact(searchTerm) {
    if (-1 !== this.name.search(searchTerm)) {
      return true;
    }
    if (-1 !== this.email.search(searchTerm)) {
      return true;
    }
    return false;
  }  
  
  static compareContact(a, b) {
    var nameCompare = compareContactName(a, b);
    if (0 !== nameCompare) {
      return nameCompare;
    }
    return compareContactEmail(a, b); 
  } 
  
  static compareContactByName(a, b) {
    return a.name.localeCompare(b.name);     
  }
  
  static compareContactByEmail(a, b) {
    return a.email.localeCompare(b.email);   
  }
}

class ContactManager {  
  constructor() {
    this.listOfContacts = [];
  }
  
  addContact(contact) {
    this.listOfContacts.push(contact);
  }
    
  removeContact(contact) {
    var returnval = false;
    
    this.listOfContacts.forEach(function(arrayContact, index, myArray) {
      if (arrayContact.equals(contact)) {
        myArray.splice(index, 1);
        returnval = true;
      }      
    });
    return returnval;
  }
  
    removeContactByIndex(index) {
    if (index < this.listOfContacts.length) {
      this.listOfContacts.splice(index, 1);
    }
  }
  
  sortContacts(sortType) {
    if (ContactManager.SortType.name === sortType) {
      this.listOfContacts.sort(Contact.compareContactByName);      
    } else if (ContactManager.SortType.email === sortType) {
      this.listOfContacts.sort(Contact.compareContactByEmail);      
    } else {
      this.listOfContacts.sort(Contact.compareContact);
    }
  }
      
  emptyContacts() {
    this.listOfContacts = [];
  }
  
  loadContacts() {
    this.emptyContacts();  
    var contactsList = this.listOfContacts;
    if (undefined !== localStorage.contactManagerList) {
      var basicObjects = JSON.parse(localStorage.contactManagerList);
      basicObjects.forEach(function(basicObject) {
        contactsList.push(new Contact(basicObject.name, basicObject.email));
      });
    }
  }
  
  saveContacts() {
    var contactList = JSON.stringify(this.listOfContacts);
    localStorage.contactManagerList = contactList;
  }
  
  printContactsToConsole() {
    console.log('Contacts: ');
    this.listOfContacts.forEach(function(arrayContact) {
      arrayContact.printContactToConsole();
    });    
  }
  
  displayContactsAsTable(displayEl, searchTerm) {
    // Clear the element that will get the table
    displayEl.innerHTML = '';    
    if (0 === this.listOfContacts.length) {
      displayEl.innerHTML = '<p>No contacts to display</p>';
      return;
    }
    
    // Create and insert the table element
    var tableEl = document.createElement('table');
    displayEl.appendChild(tableEl);

    // Create the header row
    ContactManager.addContactTableHeaderRow(tableEl);
        
    // Create and insert the contact records
    var contactsDisplayed = 0;
    for (var index = 0; index < this.listOfContacts.length; index++) {
      var contact = this.listOfContacts[index];
      if (null != searchTerm && !contact.searchContact(searchTerm)) {
        continue;        
      }  
      contactsDisplayed++;
      
      // Create a row for this contact
      ContactManager.addContactTableRow(tableEl, contact, index);
    }
    
    if (0 === contactsDisplayed) {
      displayEl.innerHTML = '<p>No contacts to display</p>';
    }    
  }  
  
  static addContactTableHeaderRow(tableEl) {
    var tableRowEl = document.createElement('tr');
    ContactManager.addTableHeader(tableRowEl, '');
    var headerNameEl = ContactManager.addTableHeader(tableRowEl, 'Name');
    headerNameEl.addEventListener('click', sortContactsByName);
    var headerEmailEl = ContactManager.addTableHeader(tableRowEl, 'Email');
    headerEmailEl.addEventListener('click', sortContactsByEmail);    
    tableEl.appendChild(tableRowEl);
  }

  static addTableHeader(tableRowEl, headerText) {
    var headerEl = document.createElement('th');
    headerEl.scope='column';
    headerEl.innerHTML = headerText;
    tableRowEl.appendChild(headerEl);
    return headerEl;
  }

  static addContactTableRow(tableEl, contact, index) {
    var tableRowEl = document.createElement('tr');
    // Create the 'delete me' data field, add it to the row
    var deleteMeDataEl = document.createElement('td');
    var imgEl = document.createElement('img');
    imgEl.src = 'http://i.imgur.com/yHyDPio.png';
    imgEl.dataset.contactId = index;
    imgEl.addEventListener('click', deleteContactRow);
    deleteMeDataEl.appendChild(imgEl);     
    tableRowEl.appendChild(deleteMeDataEl);
    // Add the contact information
    ContactManager.addTableData(tableRowEl, contact.name, index, 'name');
    ContactManager.addTableData(tableRowEl, contact.email, index, 'email');   
    // Add the row to the table
    tableEl.appendChild(tableRowEl);
  }

  static addTableData(tableRowEl, data, index, contactField) {
    // Create and add our data element
    var dataEl = document.createElement('td');
    dataEl.dataset.contactId = index;
    dataEl.dataset.contactField = contactField;    
    dataEl.addEventListener('click', beginEditContact);    
    dataEl.addEventListener('blur', endEditContact, true);        
    tableRowEl.appendChild(dataEl);
    // Add our 'label', which will show the value
    var labelEl = document.createElement('label');
    labelEl.innerHTML = data;
    labelEl.for = 'edit' + contactField + index;
    dataEl.appendChild(labelEl);
    // Add our input element, which will allow on the fly editing
    var inputEl = document.createElement('input'); 
    inputEl.id = labelEl.for;
    if ('email' === contactField) {
      // TODO: I need to do something extra to have the email validation work.
      inputEl.type = 'email';
    } else {
      inputEl.type = 'text';      
    }
    inputEl.style.display = 'none';
    inputEl.addEventListener('change', updateContact);
    dataEl.appendChild(inputEl);
    return dataEl;
  }  
}
ContactManager.SortType = {
  default: 0,
  name: 1,
  email: 2
}

var contactManager = new ContactManager();

window.onload = init;

function init() {
  var emptyEl = document.querySelector('#empty');
  emptyEl.addEventListener('click', emptyContacts);
  
  var saveEl = document.querySelector('#save');
  saveEl.addEventListener('click', saveContacts);
  
  var loadEl = document.querySelector('#load');
  loadEl.addEventListener('click', loadContacts);
  
  var searchEl = document.querySelector('#searchField');
  searchEl.addEventListener('input', searchContacts);
  
  displayContactsAsTable();
}

function addContact() {  
  var nameEl = document.querySelector('#name');
  var emailEl = document.querySelector('#email');
    
  contactManager.addContact(new Contact(nameEl.value,
                                       emailEl.value));
  
  nameEl.value = '';
  emailEl.value = '';
 
  displayContactsAsTable();
  
  return false;
}

function emptyContacts(evt) {
  contactManager.emptyContacts();  
  displayContactsAsTable();  
}

function saveContacts(evt) {
  contactManager.saveContacts();
}

function loadContacts(evt) {
  contactManager.loadContacts();   
  displayContactsAsTable();  
}

function displayContactsAsTable() {
  var contactsDivEl = document.querySelector('#contactsDiv');
  contactManager.displayContactsAsTable(contactsDivEl); 
}

function deleteContactRow(evt) {
  var indexToRemove = parseInt(evt.target.dataset.contactId);
  contactManager.removeContactByIndex(indexToRemove);
  displayContactsAsTable();
}

function searchContacts(evt) {
  var contactsDivEl = document.querySelector('#contactsDiv');  
  contactManager.displayContactsAsTable(contactsDivEl, evt.target.value);
}

function sortContactsByName(evt) {
  contactManager.sortContacts(ContactManager.SortType.name);
  displayContactsAsTable();
}

function sortContactsByEmail(evt) {
  contactManager.sortContacts(ContactManager.SortType.email);
  displayContactsAsTable();
}

function updateContact(evt) {
  var contactIndex = evt.target.parentNode.dataset.contactId;
  var newValue = evt.target.value;
  var contact = contactManager.listOfContacts[contactIndex];
  if ('name' === evt.target.parentNode.dataset.contactField) {
    contact.name = newValue;
  } else if ('email' === evt.target.parentNode.dataset.contactField) {
    contact.email = newValue;
  }
  var labelEl = evt.target.parentNode.querySelector('label');
  labelEl.innerHTML = newValue;
  labelEl.style.display='inline';
  var inputEl = evt.target.parentNode.querySelector('input');  
  inputEl.style.display='none';    
}

function beginEditContact(evt) {
  var labelEl = evt.target.parentNode.querySelector('label');
  labelEl.style.display='none';
  var inputEl = evt.target.parentNode.querySelector('input');  
  inputEl.style.display='inline';
  inputEl.focus();
}

function endEditContact(evt) {
  var labelEl = evt.target.parentNode.querySelector('label');
  labelEl.style.display='inline';
  var inputEl = evt.target.parentNode.querySelector('input');  
  inputEl.style.display='none';  
}
<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8'>
    <title>Contacts</title>
  </head>
  <body>
    <form onsubmit="return addContact();">
      <fieldset>
        <legend>New Contact</legend>
        <label for='name'>Name</abel>
        <input id='name' type='text'>
        <label for='email'>Email</abel>
        <input id='email' type='email'>  
        <br>
        <button>Add Contact</button>
      </fieldset>             
    </form>
    <h3>List of Contacts</h3>
    <div id='contactsDiv'></div>
    <br>
    <button id='empty'>Empty</button>
    <button id='save'>Save</button>
    <button id='load'>Load</button>   
    <br> 
    <label id='searchFieldLabel' for='searchField'>Search Contacts:<label>
    <input type='text' id='searchField'>
  </body>
</html>