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>