Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

agenda de contactos con localstorage #82

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mauricio/contacts/.jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"esversion": 6
}
3 changes: 3 additions & 0 deletions mauricio/contacts/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.alert {
display: none;
}
30 changes: 30 additions & 0 deletions mauricio/contacts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Contacts</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" media="screen" href="css/style.css"/>
</head>

<body>
<h1>Contacts</h1>
Nombre: <input type="text" id="name" /><br />
Móvil: <input type="text" id="mobile" /><br />
Email: <input type="text" id="email" /><br />
<button id="save">Guardar</button>
<button id="deleteAll">Eliminar todos</button>
<hr />
Buscador: <input type="text" id="search" /><br />
<button id="recover">Recuperar</button>
<button id="delete">Eliminar</button>

<p class="alert">Tienes algún campo que no es válido</p>

<hr />

<ul id="containerList"></ul>

<script src="js/main.js"></script>
</body>
</html>
198 changes: 198 additions & 0 deletions mauricio/contacts/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
(function() {
const inputs = document.querySelectorAll('input[type=text]');
const containerList = document.querySelector('#containerList');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ document.querySelector es infinitamente más lento que document.getElementById.

📖 Benchmarkhttps://jsperf.com/getelementbyid-vs-queryselector/25


const buttonSave = document.querySelector('#save');
const buttonRecover = document.querySelector('#recover');
const buttonDelete = document.querySelector('#delete');
const buttonDeleteAll = document.querySelector('#deleteAll');

buttonSave.addEventListener('click', saveContact, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muy buena abstracción! 👍

buttonRecover.addEventListener('click', recoverContact, false);
buttonDelete.addEventListener('click', deleteContact, false);
buttonDeleteAll.addEventListener('click', deleteAllContact, false);

let contactsToStorage = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Esto da lugar a confusión, el enfoque es poco funcional. Intenta evitar las variables globales!

let indexToChange = null;

function onShowDeleteAllButton(show = false) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ onShowDeleteAllButton y onShowDeleteButton son super similares. Usa un closure o pasarle un argumento para evitar repetir tanto código

if (show) {
buttonDeleteAll.style.display = 'block';
} else {
buttonDeleteAll.style.display = 'none';
}
}

function onShowDeleteButton(show = false) {
if (show) {
buttonDelete.style.display = 'block';
} else {
buttonDelete.style.display = 'none';
}
}

function init() {
onShowDeleteButton();
let data = localStorage.getItem('contacts');
if (!!data) {
data = JSON.parse(data);
contactsToStorage = data;
if (contactsToStorage && contactsToStorage.length) {
onShowDeleteAllButton(true);
}
_getDataLocalStorage(data);
} else {
onShowDeleteAllButton();
}
}

function _getDataLocalStorage (data) {
data.forEach(item => appendTemplate(item));
}

function appendTemplate(contactValues) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contactData o data o simplemente contact pienso que sería semánticamente más esclarecedor 😉

const template =
`
<li>
<div class="avatar"><img src="https://api.adorable.io/avatars/40/${contactValues.email}.png" alt="img"></div>
<div class="details">
<div class="title">${contactValues.name}</div>
<div class="phone">${contactValues.phone}</div>
<div class="email">${contactValues.email}</div>
</div>
</li>
`;

containerList.insertAdjacentHTML('afterbegin', template);
}

function saveContact() {
const values = _getValuesForm();
const isFormOk = _isFormOK(values);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isFormOk la usa solo una vez.. tiene sentido crear una variable?

if (isFormOk) {
Array.from(inputs).map(item => item.value = '');
const contactValues = _createContact(values);
appendTemplate(contactValues);
}
}

function _getValuesForm() {
return Array.from(inputs).map(item => item.value);
}

function _isFormOK(values) {
const NAME_REGEX = /\w+/g;
const PHONE_REGEX = /[0-9]+/g;
const EMAIL_REGEX = /([\w]+[\-]*[0-9]*)+@(([\w]{3,})+[\.])+([a-z]{2,3})/g;

if (values[0].match(NAME_REGEX) === null || values[1].match(PHONE_REGEX) === null || values[2].match(EMAIL_REGEX) === null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

esto debe limpiarse un poco.. con un array o similar. Enfoque más funcional

document.querySelector('.alert').style.display = 'block';
return false;
} else {
document.querySelector('.alert').style.display = 'none';
return true;
}
}

function _createContact(values) {
if (document.querySelector('#nobody')) {
document.querySelector('#nobody').remove();
}

const [name, phone, email] = values;
const contactData = {
name,
phone,
email
};

if (indexToChange === null) {
contactData.id = generateId();
contactsToStorage.push(contactData);
} else {
containerList.innerHTML = '';
contactsToStorage.splice(indexToChange, 1, contactData);
}

_setLocalStorage(contactsToStorage);
onShowDeleteAllButton(true);
return contactData;
}

function generateId() {
return Math.floor(Date.now() / 1000);
}

function recoverContact() {
const searched = document.querySelector('#search').value;
containerList.innerHTML = '';

let i;

for (i = 0; i < contactsToStorage.length; i++) {
if (contactsToStorage[i].name === searched) {
indexToChange = contactsFiltered = i;
onShowDeleteButton(true);
appendTemplate(contactsToStorage[i]);
_getContactToEdit(contactsToStorage[i]);
break;
}
}

if (indexToChange === null) {
containerList.innerHTML = `<p id="nobody">No tienes ningún contacto con el nombre: ${searched}</p>`;
}
}

function _getContactToEdit(contact) {
const {name, phone, email} = contact;
document.querySelector('#name').value = name;
document.querySelector('#mobile').value = phone;
document.querySelector('#email').value = email;
}

function deleteContact () {
name = inputs[0].value;

let contactIndex;
contactsToStorage.forEach( (item, index) => {
if (item.name === name) {
contactIndex = index;
Array.from(inputs).map(item => item.value = '');
return contactIndex;
}
});

if (contactIndex !== undefined) {
contactsToStorage.splice(contactIndex, 1);
containerList.innerHTML = '';
contactsToStorage.forEach(item => appendTemplate(item));
_updateLocalStorage(contactsToStorage);
onShowDeleteButton();
} else {
containerList.innerHTML = `No tienes ningún contacto con el nombre de: ${name}`;
}
}

function deleteAllContact() {
_deleteLocaleStorage();
onShowDeleteAllButton();
}

function _setLocalStorage (contactsToStorage) {
localStorage.setItem('contacts', JSON.stringify(contactsToStorage));
}

function _updateLocalStorage () {
localStorage.removeItem('contacts');
localStorage.setItem('contacts', JSON.stringify(contactsToStorage));
}

function _deleteLocaleStorage() {
containerList.innerHTML = '';
localStorage.removeItem('contacts');
}

init();

})();