0

i am doing the library project from "odin project" website and i am having trouble completing it. my idea is to access the cards particular index in the "library" array of objects, but i am having trouble doing so. my idea is to have a function that creates some type of id from its place in the array ( such as its index ) and use that as access for my delete button. any suggestions? i appreciate your time here is my codepen link

    //constructor to add a book to
function Book(title, author, pages) {
  this.title = title;
  this.author = author;
  this.pages = pages;
}

//array of books
const library = [];



//hides and unhides forms
const hide = () => {
  var form = document.querySelector("#hide");
  if (form.style.display === "none") {
    form.style.cssText =
      "display: block; display: flex; justify-content: center; margin-bottom: 150px";
  } else {
    form.style.display = "none";
  }
};





//creates form, takes input,creates card, resets and runs hide function when done  
const addBookCard = () => {
  const bookName = document.querySelector('input[name="bookName"]').value;
  const authorName = document.querySelector('input[name="authorName"]').value;
  const numPages = document.querySelector('input[name="numPages"]').value;
  library.push(new Book(bookName, authorName, numPages));



  //just stating variables used within my function
  const container = document.querySelector(".flex-row");
  const createCard = document.createElement("div");
  const divTitle = document.createElement("p");
  const divAuthor = document.createElement("p");
  const divPages = document.createElement("p");
  const deleteBtn = document.createElement("button");


  //using a class from my css file
  createCard.classList.add("card");
  createCard.setAttribute("id","id_num")
  deleteBtn.setAttribute("onclick", "remove()")
  deleteBtn.setAttribute('id','delBtn')

  //geting all info from library
  divTitle.textContent = "Title: " + bookName
  divAuthor.textContent = "Author: " + authorName
  divPages.textContent = "Number of Pages: " + numPages
  deleteBtn.textContent = "Delete This Book";

  //adding it all to my html
  container.appendChild(createCard);
  createCard.appendChild(divTitle);
  createCard.appendChild(divAuthor);
  createCard.appendChild(divPages);
  createCard.appendChild(deleteBtn);

  document.getElementById("formReset").reset();
  hide()
  return false
};


var btn = document.querySelector('#newCard');
btn.onclick = addBookCard; 

1 Answer 1

1

You can change library declaration from const to let.

Then you can push books together with their corresponding deleteBtn, that way you will be able to easily remove an entry that corresponds to the clicked deleteBtn

library.push([new Book(bookName, authorName, numPages), deleteBtn]);

And then you can add event listener on deleteBtn like this

deleteBtn.addEventListener('click', event => {
  event.target.parentNode.remove();
  library = library.filter(v => v[1] !== event.target);
});

Where the first line removes the element from the DOM, and the second line creates new library array without the removed entry.

function Book(title, author, pages) {
  this.title = title;
  this.author = author;
  this.pages = pages;
}

//array of books
let library = [];

//hides and unhides forms
const hide = () => {
  var form = document.querySelector("#hide");
  if (form.style.display === "none") {
    form.style.cssText =
      "display: block; display: flex; justify-content: center; margin-bottom: 150px";
  } else {
    form.style.display = "none";
  }
};



//creates form, takes input,creates card, resets and runs hide function when done
const addBookCard = () => {
  const bookName = document.querySelector('input[name="bookName"]').value;
  const authorName = document.querySelector('input[name="authorName"]').value;
  const numPages = document.querySelector('input[name="numPages"]').value;

  //just stating variables used within my function
  const container = document.querySelector(".flex-row");
  const createCard = document.createElement("div");
  const divTitle = document.createElement("p");
  const divAuthor = document.createElement("p");
  const divPages = document.createElement("p");
  const deleteBtn = document.createElement("button");

  library.push([new Book(bookName, authorName, numPages), deleteBtn]);

  deleteBtn.addEventListener('click', event => {
    event.target.parentNode.remove();
    library = library.filter(v => v[1] !== event.target);
  });

  //using a class from my css file
  createCard.classList.add("card");
  createCard.setAttribute("id","id_num")
  deleteBtn.setAttribute('id','delBtn')

  //geting all info from library
  divTitle.textContent = "Title: " + bookName
  divAuthor.textContent = "Author: " + authorName
  divPages.textContent = "Number of Pages: " + numPages
  deleteBtn.textContent = "Delete This Book";

  //adding it all to my html
  container.appendChild(createCard);
  createCard.appendChild(divTitle);
  createCard.appendChild(divAuthor);
  createCard.appendChild(divPages);
  createCard.appendChild(deleteBtn);

  document.getElementById("formReset").reset();
  hide()
  return false
};


var btn = document.querySelector('#newCard');
btn.onclick = addBookCard;



function hello (){
  for (var i = 0; i < library.length ;i++) {
    console.log(library[i]);
  }
}
body {
  margin: 0 auto;
  width: 960px;
  //background: cyan;
}

.flex-row {
  display: flex;
  flex-wrap: wrap;
}

.flex-column {
  display: flex;
  flex-direction: column;
}

.flex-row-form {
  display: flex;
  justify-content: center;
}
.flex-column-form {
  display: flex;
  flex-direction: column;
  background: purple;
  width: 45%;
  padding: 20px;
  border-radius: 5px;
  border: 2px solid black;
  color: white;
  font-weight: 300;
  font-size: 24px;
}

.card {
  width: 33.33%;
  text-align: center;
  height: 200px;
  border: 1px solid black;
  padding: 20px;
  margin: 10px;
  border-radius: 10px;
}

.text {
  padding-bottom: 20px;
  font-weight: 300;
  font-size: 20px;
}

p {
  font-size: 20px;
  font-weight: 400;
}

#newBook {
  margin: 30px;
  padding: 10px 20px;
  cursor: pointer;
  font-size: 16px;
  color: #dff;
  border-radius: 5px;
  background: black;
}

#delBtn{
  padding:10px;
  border-radius:5px;
  background:red;
  color:white;
  font-size:14px;
  cursor: pointer;
}
<div id="display"></div>

<button id="newBook" onclick="hide()">New Book</button>

<div class="flex-row-form" id="hide" style= "display:none">
  <form class="flex-column-form" id="formReset">
    Book Name: <input type="text" name="bookName" value="Book Name" id="title"><br>
    Author Name: <input type="text" name="authorName" value="Author Name " id="author"<br>
    Number of Pages: <input type="text" name="numPages" value="# of Pages" id="pages" ><br>
    <button id="newCard"> Add Book to Library</button>
  </form>
</div>

<div class="flex-row">

</div>

And I have removed this line

deleteBtn.setAttribute("onclick", "remove()")

you don't need it anymore since I have added event listener for that button, and it was throwing an error because you didn't define remove function in your code.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for breaking it down for me Matus ! what exactly is going on inside the filter() method within. i understand all except the use of 'v[1]' in the function, why the did you choose "1" and not something like "i" or any other number?
@joseperez Filter processes each element of a given array one element at a time, you don't need to specify index of that element. However each element in this case is another array consisting of two elements - [new Book(bookName, authorName, numPages), deleteBtn] first is a book entry and the second is the corresponding delete button. v[1] targets that button inside of this two-elements array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.