Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialJacek Skrzypek
5,040 PointsMy sollution with select dropdown and local storage
looking forward for any advice on how to make it better!
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('registrar');
const input = form.querySelector('input');
const mainDiv = document.querySelector('.main');
const ul = document.getElementById('invitedList');
const div = document.createElement('div');
const filterLabel = document.createElement('label');
const filterCheckbox = document.createElement('input');
const options = ["no response", "confirmed", "declined"]
filterLabel.textContent = "Hide those who haven't responded";
filterCheckbox.type = 'checkbox';
div.appendChild(filterLabel);
div.appendChild(filterCheckbox);
mainDiv.insertBefore(div, ul);
filterCheckbox.addEventListener('change', (e) => {
const isChecked = e.target.checked;
const lis = ul.children;
if (isChecked) {
for (let i = 0; i < lis.length; i++) {
let li = lis[i];
if (li.className === 'responded') {
li.style.display = '';
} else {
li.style.display = 'none';
}
}
} else {
for (let i = 0; i < lis.length; i++) {
let li = lis[i];
li.style.display = '';
}
}
});
function createLI(text, response) { //added response argument for management of the dropdown selection
function createElement(elementName, property, value) {
const element = document.createElement(elementName);
element[property] = value;
return element;
}
function appendToLI(elementName, property, value){
const element = createElement(elementName, property, value);
li.appendChild(element);
return element;
}
function appendOptions(select) {
for (let i = 0; i < options.length; i++) {
let option = document.createElement('option');
option.value = options[i];
option.text = options[i];
select.appendChild(option);
}
select.value = response; //sets response
}
const li = document.createElement('li');
appendToLI('span', 'textContent', text);
const select = appendToLI('select', 'id', 'select'); //added dropdown selection
appendOptions(select);
appendToLI('textarea', 'placeholder', 'enter your notes here');
appendToLI('button', 'textContent', 'edit');
appendToLI('button', 'textContent', 'remove');
if (supportsLocalStorage()) {
localStorage.setItem(text, response); //saves text (name) and response to localStorage
}
return li;
}
form.addEventListener('submit', (e) => {
e.preventDefault();
const text = input.value;
function checkForDuplicates(text) { //Checks for duplicates
const names = Array.from(ul.querySelectorAll('span'));
if (names.find(name => name.textContent == text)) {
return true;
} else {
return false;
}
}
if (!text) {
input.placeholder = "Enter invitees' name here"; //checks if the string is empty
} else if (checkForDuplicates(text)) {
input.value = '';
alert(`You've already invited ${text}!`);
} else {
input.value = ''
const li = createLI(text, 'no response'); // sets select.value to "no response" for new invitees
ul.appendChild(li);
}
});
ul.addEventListener('change', (e) => {
let select = event.target;
let listItem = select.parentNode;
if (select.value === "no response") {
listItem.className = '';
} else {
listItem.className = 'responded';
}
if (supportsLocalStorage()) {
localStorage.setItem(listItem.firstElementChild.textContent, select.value); //updates select.value to localStorage
}
});
ul.addEventListener('click', (e) => {
if (e.target.tagName === 'BUTTON') {
const button = e.target;
const li = button.parentNode;
const ul = li.parentNode;
const action = button.textContent;
const select = li.querySelector('select');
const nameActions = {
remove: () => {
ul.removeChild(li);
if (supportsLocalStorage()) {
localStorage.removeItem(li.firstElementChild.textContent); //removes from localStorage - make DRY?
}
},
edit: () => {
if (supportsLocalStorage()) {
localStorage.removeItem(li.firstElementChild.textContent); //removes from localStorage - make DRY?
}
const text = document.createElement('input')
const span = li.firstElementChild;
text.type = 'text';
text.value = span.textContent;
li.insertBefore(text, span);
li.removeChild(span);
button.textContent = 'save'
},
save: () => {
const input = li.firstElementChild;
const span = document.createElement('span');
span.textContent = input.value;
li.insertBefore(span, input);
li.removeChild(input);
button.textContent = 'edit';
if (supportsLocalStorage()) {
localStorage.setItem(span.textContent, select.value); //saves text (name) to localStorage with previous select.value
}
}
}
// select & run action in button's name
nameActions[action]();
}
});
function supportsLocalStorage() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch(e) {
return false;
}
}
window.onload = function() { //onload check supportsLocalStorage, load names and responses pairs, build lis with createLi() and ul.appendChild
if (supportsLocalStorage()) {
const keys = Object.keys(localStorage);
if (keys.length > -1) {
for (let i = 0; i < keys.length; i++) {
const li = createLI(keys[i], localStorage.getItem(keys[i]));
ul.appendChild(li);
}
}
}
}
});
1 Answer
KRIS NIKOLAISEN
54,971 PointsThe only comments I have so far:
1) The location of your buttons, textarea and options changes based on the number of items in a row and looks especially odd with 3 items.
2) Checking 'Hide those who haven't responded" doesn't hide newly created items until you uncheck and check again.
Jacek Skrzypek
5,040 PointsJacek Skrzypek
5,040 PointsHi Kris, thanks for your review!
ad 1. - I haven't worked on the looks yet, but I plan to:)
ad 2. should be better now: