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 trial

JavaScript

My Challenge Solution

I made this function using the material taught in the course:

function updateButtonDisplay(ul) {
  // Set 1st element's 'up button' to hidden
  ul.firstElementChild.querySelector('.up').style.visibility = 'hidden';
  // Set 2nd element's 'up button' to shown
  ul.firstElementChild.nextElementSibling.querySelector('.up').style.visibility = 'visible';  
  // Set last element's 'down button' to hidden
  ul.lastElementChild.querySelector('.down').style.visibility = 'hidden';
  // Set second to last element's 'down button' to shown
  ul.lastElementChild.previousElementSibling.querySelector('.down').style.visibility = 'visible';
}

It updates the visibility of the 'up button' on the first 2 items in the list and the 'down button' on the last 2 items in the list. The function could have used the global const listUl instead of taking a parameter. However this way the function might be reused for additional lists in the future.

It is called when:

1. The list is initialized

for (let i=0; i<lis.length; i++) {
  attachListItemButtons(lis[i]);
}
updateButtonDisplay(listUl);

2. After any button is clicked

/* Manipulate items with buttons */
listUl.addEventListener('click', (event) => {
  if (event.target.tagName == 'BUTTON') {
    let li = event.target.parentNode; 
    let ul = li.parentNode; 
    /* Remove item */
    if (event.target.className == 'remove') {
        ul.removeChild(li); 
    }
    /* Move item up */
    if (event.target.className == 'up') {
        let prevLi = li.previousElementSibling; 
        if(prevLi) {
          ul.insertBefore(li, prevLi); 
        }
    }
    /* Move item down */
    if (event.target.className == 'down') {
        let nextLi = li.nextElementSibling;
        if(nextLi) {
          ul.insertBefore(nextLi, li) 
        }
    }
    updateButtonDisplay(listUl);
  }
});

3. An item is added to the list

/* Add item to the list */
addItemButton.addEventListener('click', () => {
  let ul = document.getElementsByTagName('ul')[0];
  let li = document.createElement('li');
  li.textContent = addItemInput.value;
  attachListItemButtons(li);
  ul.appendChild(li);
  addItemInput.value = '';
  updateButtonDisplay(listUl);
});

Any suggestions or comments regarding best practises is appreciated.