Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function mainSetup() {
  2.   // add item to the end of the list
  3.   const mainContainer = document.getElementById("main");
  4.   const addButton = document.createElement("button");
  5.   addButton.textContent = "Add item";
  6.   addButton.addEventListener('click', () => createItem(mainContainer));
  7.   mainContainer.appendChild(addButton);
  8. }
  9.  
  10. // create icon using fontAwesome
  11. function createIcon(fontAwesomeClass, tooltip, container) {
  12.   const icon = document.createElement("i");
  13.   icon.classList.add('fas', fontAwesomeClass);
  14.   icon.setAttribute('title', tooltip);
  15.   container.appendChild(icon);
  16.   return icon;
  17. }
  18.  
  19. // get the siblings of an element
  20. function getSiblings(elem) {
  21.     let siblings = [];
  22.     let sibling = elem.parentNode.firstChild;
  23.     while (sibling) {
  24.         if (sibling.nodeType === 1 && sibling !== elem) {
  25.             siblings.push(sibling);
  26.         }
  27.         sibling = sibling.nextSibling
  28.     }
  29.     return siblings;
  30. };
  31.  
  32. function createItem(parent) {
  33.   let list = parent.querySelector('.list');
  34.   if (!list) {
  35.     list = document.createElement('ul');
  36.     list.classList.add('list');
  37.     parent.append(list);
  38.   }
  39.  
  40.   const listItem = document.createElement("li");
  41.   listItem.classList.add('list-item', 'editable');
  42.   const expandable = document.createElement("details");
  43.   expandable.setAttribute('open', 'true');
  44.   const expandableSummary = document.createElement("summary");
  45.   const detailsContainer = document.createElement("div");
  46.   detailsContainer.classList.add('details');
  47.   const div = document.createElement("div");
  48.   const input = document.createElement("input");
  49.   input.classList.add('text-input');
  50.   const text = document.createElement("span");
  51.   text.classList.add('text-container');
  52.  
  53.   const err = document.createElement("span");
  54.   err.textContent = "Please enter some text before pressing Enter."
  55.   err.setAttribute('style', 'display:none;');
  56.  
  57.   // hide the input field and save the text when pressing the ENTER key
  58.   input.addEventListener('keydown', event => {
  59.     if(event.key === 'Enter') {
  60.       if (input.value.length) {
  61.         text.textContent = input.value;
  62.         input.setAttribute('style', 'display:none;');
  63.         err.setAttribute('style', 'display:none;');
  64.       }
  65.       else {
  66.         err.setAttribute('style', 'display:visible;');
  67.         err.setAttribute('style', 'color: red;');
  68.       }
  69.     }
  70.   })
  71.  
  72.   div.appendChild(input);
  73.   div.appendChild(err);
  74.   detailsContainer.appendChild(text);
  75.   expandableSummary.appendChild(detailsContainer);
  76.   expandableSummary.appendChild(div);
  77.   expandable.appendChild(expandableSummary);
  78.   listItem.appendChild(expandable);
  79.   list.appendChild(listItem);
  80.   input.focus();
  81.  
  82.   // hide the input field on blur
  83.   input.addEventListener('blur', () => {
  84.     if (text.textContent.length) {
  85.       listItem.classList.remove('editable');
  86.     } else {
  87.       listItem.remove();
  88.     }
  89.   })
  90.  
  91.   // display the edit, add, delete and complete icons in a container, next to the list item
  92.   const iconsContainer = document.createElement("span");
  93.   iconsContainer.classList.add('icons-container');
  94.   detailsContainer.appendChild(iconsContainer);
  95.  
  96.   const editIcon = createIcon('fa-edit', 'Edit item', iconsContainer);
  97.   const addIcon = createIcon('fa-plus', 'Add item', iconsContainer);
  98.   const deleteIcon = createIcon('fa-trash-alt', 'Delete item', iconsContainer);
  99.   const checkIcon = createIcon('fa-check', 'Check item', iconsContainer);
  100.   const uncheckIcon = createIcon('fa-times-circle', 'Uncheck item', iconsContainer);
  101.   uncheckIcon.setAttribute('style', 'display:none;');
  102.  
  103.   // stop bubbling up on iconsContainer elements
  104.   iconsContainer.addEventListener('click', (event) => {
  105.     if(event.target && event.target.nodeName == "I") {
  106.           event.preventDefault();
  107.       }
  108.   })
  109.  
  110.   // After collapsing and then expanding, all the childrens should have their children list collapsed.
  111.   expandable.addEventListener("toggle", () => {
  112.     if (!expandable.open) {
  113.       const childExpandables = expandable.querySelectorAll('details');
  114.       childExpandables.forEach(item => item.removeAttribute('open'));
  115.     }
  116.   });
  117.  
  118.   // add functionality for the addIcon
  119.   addIcon.addEventListener('click', () => createItem(expandable));
  120.  
  121.   // add functionality for the editIcon
  122.   editIcon.addEventListener('click', () => {
  123.     listItem.classList.add('editable');
  124.     input.value = text.textContent;
  125.     input.setAttribute('style', 'display:initial;');
  126.     input.focus();
  127.   });
  128.  
  129.   // add functionality for the deleteIcon
  130.   deleteIcon.addEventListener('click', () => {
  131.     let childList = listItem.querySelector('.list');
  132.     if (childList) {
  133.       let notification = confirm("Atention! This item has children and they will be also removed!");
  134.       if (notification == true) {
  135.         listItem.remove();
  136.       }
  137.     }
  138.     else {
  139.       listItem.remove();
  140.     }
  141.     if (!list.querySelector('.list-item')) {
  142.       list.remove();
  143.     }
  144.   });
  145.  
  146.   // add functionality for the checkIcon
  147.   checkIcon.addEventListener('click', (event) => {
  148.     const parentLi = event.target.closest('.list-item');
  149.     // console.log(parentLi);
  150.     if (parentLi.querySelector('.list-item')) {
  151.       console.log (parentLi.querySelector('.list-item'));
  152.       return;
  153.     }
  154.     text.setAttribute('style', 'text-decoration: line-through;');
  155.     checkIcon.setAttribute('style', 'display:none;');
  156.     uncheckIcon.setAttribute('style', 'display:initial;');
  157.     let ok = true;
  158.  
  159.     const parentLiSiblings = getSiblings(parentLi);
  160.     parentLiSiblings.forEach(item => {
  161.       if (item.querySelector('.fa-check').getAttribute('style') !== 'display:none;') {
  162.         ok = false;
  163.       }
  164.     });
  165.     if (ok) {
  166.       parentLi.parentNode.closest('.list-item').querySelector('.fa-check').click();
  167.     }
  168.   });
  169.  
  170.   // add functionality for the uncheckIcon
  171.   uncheckIcon.addEventListener('click', () => {
  172.     text.setAttribute('style', 'text-decoration: none;');
  173.     uncheckIcon.setAttribute('style', 'display:none;');
  174.     checkIcon.setAttribute('style', 'display:initial;');
  175.   });
  176. }
  177.  
  178. mainSetup();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement