skip to Main Content

Here is my almost finished bookshelf, however I want to be able to delete any entry by clicking on the book for the details and then clicking the delete button that will appear.
So far, it will delete the book from the shelf but then it refreshes and the book has returned but the first book is deleted.

I’ve been working on this for a while and I can figure out what I’m doing wrong, if any body could help I would appreciate it.

//localStorage.clear();
const
  localStorageKey = 'storedbookShelf',
  shelf           = document.getElementById('shelf'),
  addBookBtn      = document.getElementById('add-book'),
  clearBooksBtn   = document.getElementById('clear-books'),
  myForm          = document.getElementById('form'),
  formDiv         = document.getElementById('formcontainer'),
  submitFormBtn   = document.getElementById('submitform'),
  bookCard        = document.getElementById('bookcard'),
  showAll         = document.querySelector('#showall tbody'),
  removeBtn       = document.querySelector('#remove-book'),
  upBtn           = document.querySelector('button.up'),
  downBtn         = document.querySelector('button.down'),
  bookShelf       = JSON.parse(localStorage.getItem(localStorageKey) || '[]'),
  booksElms        = [];

///// OPEN FORM /////

addBookBtn.addEventListener('click', () => {
  formDiv.classList.remove('no-display');
  document.getElementById('booktitle').focus();
});

/////     /////


///// ADD BOOK ELEMENT TO SHELF /////

function addBookFnc(title) {
  let book = document.createElement('div');

  book.classList.add('book');
  if (title) {
    book.textContent = title;
  }
  shelf.appendChild(book);
  booksElms.push(book);
}

if (bookShelf) {
  bookShelf.forEach(book => {
    addBookFnc(book ? .title);
  });
}

function addBookForm() {
  let hasEmptyBook = false;

  booksElms.forEach(book => {
    // set value if empty
    if (book.textContent == '') {
      book.textContent = myForm.booktitle.value;
      hasEmptyBook = true;
    }
  });

  if (hasEmptyBook === false) return '';
}


/////    /////

///// STORE BOOK DETAILS /////

function BookDetails(title, author, pages, pagesread, completed, recommended) {
  this.title       = title,
  this.author      = author,
  this.pages       = pages,
  this.pagesread   = pagesread,
  this.completed   = completed,
  this.recommended = recommended
}

function updateBookShelf() {

  let title       = document.getElementById("booktitle").value;
  let author      = document.getElementById("author").value;
  let pages       = document.getElementById("pages").value;
  let pagesread   = document.getElementById("pagesread").value;
  let completed   = document.getElementById("completed").checked;
  let recommended = document.getElementById("recommended").checked;

  ///// CHECK PAGES VS PAGES READ /////

  if (pages == pagesread) {
    completed = true;
  }

  let newBook = new BookDetails(title, author, pages, pagesread, completed, recommended);

  bookShelf.push(newBook);

}


myForm.addEventListener('submit', e => {
  e.preventDefault();
  addBookFnc();
  updateBookShelf();
  addBookForm();


  formDiv.classList.add('no-display');
  myForm.reset();

  updateStorage();

});

/////    /////

///// OPEN BOOK CARD /////


var books = document.querySelectorAll('.book');
for (let b = 0; b < books.length; b++) {

  books[b].addEventListener('click', function() {

    bookCard.classList.remove('no-display');
    let book             = bookShelf[b];
    let titleSpace       = document.querySelector('h3.title');
    let authorSpace      = document.querySelector('p.author');
    let pagesSpace       = document.querySelector('span.pages');
    let pagesReadSpace   = document.querySelector('span.pagesread');
    let completedSpace   = document.querySelector('div.completed p');
    let recommendedSpace = document.querySelector('div.recommended p');

    titleSpace.innerHTML     = book.title;
    authorSpace.innerHTML    = book.author;
    pagesSpace.innerHTML     = book.pages;
    pagesReadSpace.innerHTML = book.pagesread;
    let completedValue       = book.completed;
    let recommendedValue     = book.recommended;

    /////     /////

    if (completedValue == true) {
      completedSpace.innerHTML = 'You have completed this book.';
    } else {
      completedSpace.innerHTML = 'You have not yet completed this book.';
    }

    if (recommendedValue == true) {
      recommendedSpace.innerHTML = "You would recommend this book.";
    } else {
      recommendedSpace.innerHTML = "";
    }



    //// REMOVE BOOK /////

    removeBtn.style.display = 'inline-block';

    function removeBook() {
      books[b].remove();
      bookShelf.splice(book, 1);
      updateStorage();
      window.location.reload();
    }

    removeBtn.onclick = () => removeBook();

    updateStorage();
  })
};


/////    /////

function updateStorage() {
  localStorage.setItem(localStorageKey, JSON.stringify(bookShelf));
}

console.log(bookShelf)
h1,
h2,
h3,
p,
label {
  font-family: 'Roboto', sans-serif;
}

#main-table {
  display: grid;
  gap: 15px;
  padding: 15px;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 130px 2fr 2fr;
  border: 2px solid #000;
}

header {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-column: span 4;
}

#logo {
  grid-column-start: 1;
}

#logo img {
  max-width: 120px;
}

#page-title {
  align-self: center;
  justify-self: center;
}

#account-area {
  align-self: center;
  justify-self: right;
}

#account-area img {
  max-height: 50px;
}

#bookdisplay {
  grid-column: span 4;
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 15px;
  align-items: center;
}

#bookshelf {
  display: grid;
  grid-auto-rows: 150px;
  align-items: end;
  padding: 15px 15px 0px 15px;
  border: 2px solid #000;
  border-radius: 10px;
  height: 180px;
  overflow-y: scroll;
  border-bottom: 5px solid #000;
}

#shelf {
  height: 150px;
  border-bottom: 5px solid #000;
  display: grid;
  row-gap: 80px;
  grid-template-columns: repeat(auto-fill, minmax(25px, 40px));
  align-items: end;
}

.book {
  border: 1px solid #000;
  height: 100px;
  width: 25px;
  display: inline-block;
  padding-top: 5px;
  writing-mode: vertical-rl;
  font-family: 'Roboto', sans-serif;
  cursor: pointer;
  text-wrap: nowrap;
  overflow: hidden;
  padding-bottom: 5px;
}

.book p {
  transform: rotate(90deg);
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}

#page {
  grid-column: span 4;
}

#add-book,
#remove-book button {
  font-size: 32px;
  color: #fff;
  font-weight: bold;
  border: none;
  padding: 5px;
  width: 50px;
  height: 50px;
  border-radius: 5px;
  cursor: pointer;
}

#add-book {
  background-color: darkcyan;
}

#remove-book button {
  background-color: red;
}

.button-row h3 {
  display: inline-block;
  margin: 0 30px 0 10px;
}


/*** FORM ***/

#form {
  position: absolute;
  top: 10%;
  left: 30%;
  background: #fff;
  padding: 20px;
  border: 1px solid #000;
  border-radius: 15px;
}

.no-display {
  display: none;
}

#form h2 {
  text-align: center;
  margin-top: 0;
}

#form input {
  margin: 5px 0 10px 0;
}

#form input[type=text] {
  height: 30px;
  width: 75%;
  font-weight: bold;
  color: darkcyan;
  padding-left: 5px;
}

#submitform {
  background-color: darkcyan;
  color: #fff;
  font-weight: bold;
  border: none;
  padding: 5px;
  width: 50%;
  height: 30px;
  border-radius: 5px;
}


/**** BOOK CARD ****/

#bookcard {
  border: 1px solid #000;
  padding: 15px;
  border-radius: 15px;
}

#bookcard .title {
  margin-top: 0;
  text-align: center;
}

#bookcard .author {
  text-align: right;
}

#bookcard .amountread button {
  background-color: cornflowerblue;
  color: #fff;
  font-weight: bold;
  border-radius: 5px;
  border: 1px solid #000;
  height: 25px;
  width: 25px;
}

#bookcard .amountread .down {
  margin: 0 10px 0 10px;
}

.completed {
  margin-bottom: 15px;
}

.completed p,
.recommeded p {
  display: inline;
}


/***** Toggle switch *****/

.switch {
  position: relative;
  display: inline-block;
  width: 45px;
  height: 25px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 5px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked+.slider {
  background-color: darkcyan;
}

input:focus+.slider {
  box-shadow: 0 0 1px darkcyan;
}

input:checked+.slider:before {
  -webkit-transform: translateX(16px);
  -ms-transform: translateX(16px);
  transform: translateX(16px);
}


/* Rounded sliders */

.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}
<div id="wrapper">

  <div container id="main-table">

    <header>

      <div id="logo">
        <a href="#"><img src="images/logo.jpg" alt="Library Logo"></a>
      </div>
      <div id="page-title">
        <h1>My Library</h1>
      </div>
      <div id="account-area">
        <a href="#"><img src="images/myaccount.png"></a>
      </div>


    </header>
    <!-- End header -->

    <div id="bookdisplay">
      <div id="bookshelf">
        <div id="shelf"></div>
      </div>
      <div id="bookinfo">
        <div id="bookcard" class="no-display">
          <h3 class="title">$Book Title</h3>
          <p class="author">%Author</p>
          <p><strong>Book Length:</strong> <span class="pages">$no</span> pages</p>
          <p class="amountread"><strong>Amount read:</strong> <span class="pagesread">$no</span> pages</p>
          <div class="completed">
            <p>You have not yet completed this book.</p>
          </div>
          <div class="recommended">
            <p>$Recommended</p>
          </div>
        </div>
      </div>
    </div>
    <!-- End #bookdisplay -->

    <div id="page">
      <div class="button-row">
        <button id="add-book">+</button>
        <h3>Add New Book</h3>
        <div id="remove-book" class="no-display"><button>-</button>
          <h3>Remove Book</h3>
        </div>
      </div>
      <div id="formcontainer" class="no-display">
        <form id="form">
          <h2>Add a new book</h2>
          <label for="booktitle">Book Title</label><br>
          <input type="text" id="booktitle" name="booktitle" required><br>
          <label for="author">Author</label><br>
          <input type="text" id="author" name="author" required><br>
          <label for="pages">Number of Pages</label><br>
          <input type="number" value="1" id="pages" name="pages" required><br>
          <label for="pagesread">Amount of Pages Read</label><br>
          <input type="number" value="1" id="pagesread" name="pagesread" required><br>
          <input type="checkbox" id="completed" name="completed">
          <label for="completed">Have you completed this book?</label><br>
          <input type="checkbox" id="recommended" name="recommended">
          <label for="recommended">Would you recommend this book?</label><br>
          <input type="submit" id="submitform" value="Submit">
        </form>
      </div>
    </div>
    <!-- End #page -->

  </div>
  <!-- End #main-table -->

</div>
<!-- End #wrapper -->

2

Answers


  1. bookShelf.splice(book, 1); is already a good start, but Array.splice takes an index as first argument, not an object. So before you can use splice to remove the element from the array, you have find which index to remove. For instance using Array.findIndex

    let bookIndex = bookShelf.findIndex(x => x.title === book.title)
    if (bookIndex >= 0)
      bookShelf.splice(bookIndex, 1);
    updateStorage();
    

    If your booktitles are distinct (or you have any other identifiying property which is distinct) you could also use Array.filter

     bookShelf = bookShelf.filter(x => x.title !== book.title);
    
    Login or Signup to reply.
  2. First, let’s understand how splice works,

    array.splice(index, howmany, item1, ....., itemX)
    

    index – Required. The position to add/remove items. Negative value defines the position from the end of the array.

    howmany – Optional. Number of items to be removed.

    item1, …, itemX – Optional. New elements(s) to be added.

    In our case we need to remove one element at the given index. So it will be

     bookShelf.splice(b, 1); // bookshelf.splice(index, 1);
    

    The entire code will look like,

    function removeBook() {
      bookShelf.splice(b, 1);
      updateStorage();
      window.location.reload();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search