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

MIGUEL ANGEL ALCALA ROMERO
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
MIGUEL ANGEL ALCALA ROMERO
Full Stack JavaScript Techdegree Graduate 19,948 Points

Here's my solution!! All feedbacks are welcome!

Hi all, here's my proposal to solve last question. I've worked with button's visibility property (and no display one in order to leave the space ocuppied of the button element) in other to not remove and create the same element each time, so I create a function that check and change button's visibility of a given list element having different scenarios:

  • it's the first list element so hide 'up' button --> if we already have attached all button to all list elements, show 'up' button of the second list element that was the first element and had 'up' button hidden.
  • It's the last list element so hide down button, and show the previous last item 'down' button.
  • It's a new element so it's the last element so hide 'down' button and show again 'down' button of the old last item.

Thank you for your attention and time, I hope it can help someone and I will apreciate any feedback.

const toggleList = document.getElementById('toggleList');
const listDiv = document.querySelector('.list');
const descriptionInput = document.querySelector('input.description');
const descriptionP = document.querySelector('p.description');
const descriptionButton = document.querySelector('button.description');
const listUl = listDiv.querySelector('ul');
const addItemInput = document.querySelector('input.addItemInput');
const addItemButton = document.querySelector('button.addItemButton');
const lis = listUl.children;
const firstListItem = listUl.firstElementChild;
const lastListItem = listUl.lastElementChild;

firstListItem.style.backgroundColor = 'lightskyblue';
lastListItem.style.backgroundColor = 'lightsteelblue';

/***
* change visibility of up button or down button of the li element
* and his previous li element or next li element if it is the first
* or last element of the ul
***/
function checkButtons(li) {
  let ul = li.parentNode;

  if (ul.firstElementChild == li) {
    let firstUp = li.querySelector('button.up');
    let secondLi = li.nextElementSibling;
    let secondUp = secondLi.querySelector('button.up');

    firstUp.style.visibility = 'hidden';
    // If we are in first attachment we havent attached buttons in
    // the next li element yet.
    if(secondUp){
      secondUp.style.visibility = 'visible';
    }
  }

  if (ul.lastElementChild == li) {
    let penultimateLi = li.previousElementSibling;
    let penultimateDown = penultimateLi.querySelector('button.down');
    let lastDown = li.querySelector('button.down');

    lastDown.style.visibility = 'hidden';
      penultimateDown.style.visibility = 'visible';
  }
}

function attachLisItemButtons (li) {
  let ul = li.parentNode;

  let up = document.createElement('button');
  up.className = 'up';
  up.textContent = 'Up';
  li.appendChild(up);

  let down = document.createElement('button');
  down.className = 'down';
  down.textContent = 'Down';
  li.appendChild(down);

  if (ul) {
    // we are attaching in a preexisting ul
    checkButtons(li);
  } else {
    // we are attaching in a new li
    down.style.visibility = 'hidden';
  }
  let remove = document.createElement('button');
  remove.className = 'remove';
  remove.textContent = 'Remove';
  li.appendChild(remove);
}

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

listUl.addEventListener('click', (event) => {
  if ( event.target.tagName == 'BUTTON' ) {
    if (event.target.className == 'remove') {
      let li = event.target.parentNode;
      let ul = li.parentNode;
      ul.removeChild(li);
    }
    if (event.target.className == 'up') {
      let li = event.target.parentNode;
      let prevLi = li.previousElementSibling;
      let ul = li.parentNode;
      if (prevLi) {
        ul.insertBefore(li,prevLi);
      }
      // Check if li is the new first li of ul
      // so hide up button
      checkButtons(li);
      // Check if prevli was the penultimate li and now the last
      // so hide down button and show down button of li
      checkButtons(prevLi);
    }
    if (event.target.className == 'down') {
      let li = event.target.parentNode;
      let nextLi = li.nextElementSibling;
      let ul = li.parentNode;
      if (nextLi) {
        ul.insertBefore(nextLi,li);
      } 
      // Check if li is the new last li of ul
      // so hide down button
      checkButtons(li);
      // Check if nextLi was the second li and now the first
      // so hide up button and show up button in li
      checkButtons(nextLi);
    }
  }
});


myHeading.textContent = "This is a new heading";

toggleList.addEventListener('click', () => {
 if (listDiv.style.display == 'none') {
    toggleList.textContent = 'Hide list';
    listDiv.style.display = "block";
  }else {
    toggleList.textContent = 'Show list';
    listDiv.style.display = "none";
  }
});

descriptionButton.addEventListener('click', () => {
  descriptionP.innerHTML = descriptionInput.value + ':';
  descriptionInput.value = '';                                 
});

addItemButton.addEventListener('click', () => {
  let ul = document.getElementsByTagName('ul')[0];
  let li = document.createElement('li');
  li.textContent = addItemInput.value;
  attachLisItemButtons(li);
  ul.appendChild(li);
  // now we need to check down button of the new penultimate li
  checkButtons(li);
  addItemInput.value = '';
});