skip to Main Content

i think every thing is good. This is the first time I have such a problem
i save tags array in local and when page reload i get information from local storage but when page reload i get a empty string in localstorage and i get that in my list tag. i dont know where empty string add to array and how remove that

const input = document.querySelector('input')
const removeAllBtn = document.querySelector('.removeAll')
const tagListContainer = document.querySelector('.tagListContainer')
let counterText = document.querySelector('.details p span')

let tags = [];

let currentNumber = 10


//***********counter number ************/
function count () {
    input.focus()
    counterText.textContent = currentNumber -  tags.length
}


//***********Remove all tags ************/
removeAllBtn.addEventListener('click', () => {
    tags = []
    removePreviousTag()
    count()
    setDataToLocal()
})


//***********Remove tags by clicking ************/
function removeTag (tagElem, tagValue) {
    tagElem.parentElement.remove()
    
    let findIndexTag = tags.indexOf(tag => tag === tagValue)

    tags.splice(findIndexTag, 1)

    count()
    setDataToLocal()
}


//***********Remove tags before adding ************/
function removePreviousTag () {
    setDataToLocal()
    tagListContainer.querySelectorAll('li').forEach(tag => tag.remove())
}

//***********Generate tag ************/
function generateTag () {
    let tagTitle = input.value.toLowerCase().trim()

    //push tow string with , in array
    tagTitle.split(',').forEach(tag => {
        tags.push(tag);
    });

    [...tags].reverse().forEach(tag => {
        const html = `<li>${tag} <i class="uit uit-multiply" onclick="removeTag(this, '${tag}')"></i></li>`
        tagListContainer.insertAdjacentHTML("afterbegin", html)
    })
    
    count()
    setDataToLocal()

    input.value = ''
};



input.addEventListener('keypress', (e) => {
    if (e.key === 'Enter' && tags.length < 10 && input.value !== '' && !tags.includes(input.value.toLowerCase())) {
        removePreviousTag()
        generateTag()
    }
})


//***********Set data in local storage ************/
function setDataToLocal () {
        localStorage.setItem('tags', JSON.stringify(tags))
}

//***********get data from local storage ************/
window.addEventListener('load', () => {
    let getData = JSON.parse(localStorage.getItem('tags'))
    if (getData?.length) {
        tags = getData
        removePreviousTag()
        generateTag()
    }
})

html code

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Tags Generator</title>
    <link rel="stylesheet" href="css/style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Unicons CDN Link for Icons -->
    <link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.0/css/thinline.css">
  </head>
  <body>
    <div class="wrapper">
      <div class="title">
        <img src="tag.svg" alt="icon">
        <h2>Tags</h2>
      </div>
      <div class="content">
        <p>Press enter or add a comma after each tag</p>
        <ul class="tagListContainer">
          <!-- Add Tags Here -->
          <input type="text" spellcheck="false" />
        </ul>
      </div>
      <div class="details">
        <p><span>10</span> tags are remaining</p>
        <button class="removeAll">Remove All</button>
      </div>
    </div>

    <script src="js/script.js"></script>
    
  </body>
</html>

css code

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: #5372f0;
}

::selection {
  color: #fff;
  background: #5372f0;
}

.wrapper {
  width: 496px;
  background: #fff;
  border-radius: 10px;
  padding: 18px 25px 20px;
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.06);
}

.wrapper :where(.title, li, li i, .details) {
  display: flex;
  align-items: center;
}

.title img {
  max-width: 21px;
}

.title h2 {
  font-size: 21px;
  font-weight: 600;
  margin-left: 8px;
}

.wrapper .content {
  margin: 10px 0;
}

.content p {
  font-size: 15px;
}

.content ul {
  display: flex;
  flex-wrap: wrap;
  padding: 7px;
  margin: 12px 0;
  border-radius: 5px;
  border: 1px solid #a6a6a6;
}

.content ul li {
  color: #333;
  margin: 4px 3px;
  list-style: none;
  border-radius: 5px;
  background: #f2f2f2;
  padding: 5px 8px 5px 10px;
  border: 1px solid #e3e1e1;
}

.content ul li i {
  height: 20px;
  width: 20px;
  color: #808080;
  margin-left: 8px;
  font-size: 12px;
  cursor: pointer;
  border-radius: 50%;
  background: #dfdfdf;
  justify-content: center;
}

.content ul input {
  flex: 1;
  padding: 5px;
  border: none;
  outline: none;
  font-size: 16px;
}

.wrapper .details {
  justify-content: space-between;
}

.details button {
  border: none;
  outline: none;
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  padding: 9px 15px;
  border-radius: 5px;
  background: #5372f0;
  transition: background 0.3s ease;
}

.details button:hover {
  background: #2c52ed;
}

2

Answers


  1. generateTag function is called from load

    window.addEventListener(‘load’, () => {

    in script.js
    you could just add in generateTag function, something like:

    function generateTag () {
        let tagTitle = input.value.toLowerCase().trim()
        if (tagTitle?.length === 0) {
            return;
        }
    
    Login or Signup to reply.
  2. When you are reloading the page then you are calling generateTag function and at that time tagTitle is empty string. Hence it is adding an empty string in the tags list.

    You can add a simple check that if the tagTitle is NOT an empty string then only add that tag otherwise don’t add it in tags list.

    //***********Generate tag ************/
    function generateTag() {
      let tagTitle = input.value.toLowerCase().trim();
    
    // ✅ Check if tagTitle is NOT an empty string 
      if (tagTitle !== '') {
        tagTitle.split(',').forEach((tag) => {
          tags.push(tag);
        });
      }
    
      [...tags].reverse().forEach((tag) => {
        const html = `<li>${tag} <i class="uit uit-multiply" onclick="removeTag(this, '${tag}')"></i></li>`;
        tagListContainer.insertAdjacentHTML('afterbegin', html);
      });
    
      count();
      setDataToLocal();
    
      input.value = '';
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search