Tell us what’s happening:
Hello there!
Regarding this lab: https://www.freecodecamp.org/learn/full-stack-developer/lab-bookmark-manager-app/build-a-bookmark-manager-app
I have some issues with the tests 18, 19, 20, 22 & 23 regarding the way I update categoryList.innerHTML and the way I delete the elements.
But when I test it, everything seems to just work fine and so does the browser’s localStorage.
Is there something wrong with what I wrote or do I miss something ?
Your code so far
/* file: script.js */
//Références vers les éléments du DOM
const mainSection = document.getElementById("main-section");
const formSection = document.getElementById("form-section");
const bookmarkListSection = document.getElementById("bookmark-list-section");
const addBookmarkBtn = document.getElementById("add-bookmark-button");
const categoryName = document.querySelectorAll(".category-name");
const category = document.getElementById("category-dropdown");
const closeFormBtn = document.getElementById("close-form-button");
const addBookmarkFormBtn = document.getElementById("add-bookmark-button-form");
const nameInput = document.getElementById("name");
const urlInput = document.getElementById("url");
const viewCategoryBtn = document.getElementById("view-category-button");
const categoryList = document.getElementById("category-list");
const closeListBtn = document.getElementById("close-list-button");
const deleteBookmarkBtn = document.getElementById("delete-bookmark-button");
// Récupération du tableau depuis le localStorage ou initialisation d'un tableau vide
const getBookmarks = () => {
try {
if (!localStorage.getItem("bookmarks")) {
return []; // Si la clé "bookmarks" n'existe pas, la f° retourne un tab vide
}
const bookmarks = JSON.parse(localStorage.getItem("bookmarks"));
const isValidArray = Array.isArray(bookmarks) && bookmarks.every(isValidBookmark); // Test pour s'assurer que bookmarks soit bien un Array et test de la validité de chaque objet de bookmarks
return isValidArray ? bookmarks : []; // Si tout est OK, la f° retourne bookmarks. Sinon elle retourne un tab vide.
} catch(error) {
return [];
}
}
//Pour tous les éléments du tab en localStorage, la f° vérifie si l'élément est un objet existant et qu'il contienne bien les 3 clés : name, category, url afin de s'assurer de la validité de l'élément comme bookmark
const isValidBookmark = bookmark => {
return bookmark !== null && typeof bookmark === "object"
&& "name" in bookmark && "category" in bookmark && "url" in bookmark;
}
const displayOrCloseForm = () => {
mainSection.classList.toggle("hidden");
formSection.classList.toggle("hidden");
}
const resetForm = () => {
nameInput.value = "";
urlInput.value = "";
}
const displayOrHideCategory = () => {
mainSection.classList.toggle("hidden");
bookmarkListSection.classList.toggle("hidden");
}
const displayBookmarkList = () => {
categoryList.innerHTML = "";
const bookmarkList = getBookmarks();
const matchingList = bookmarkList.filter(bookmark => bookmark.category === category.value);
if (!matchingList.length) {
categoryList.innerHTML = '<p>No Bookmarks Found</p>';
} else {
matchingList.forEach(({name, category, url}) => {
categoryList.innerHTML += `
<label for="${name}">
<input type="radio" id="${name}" name="link-btn" value="${name}" />
<a href="${url}">${name}</a>
</label>`;
});
}
}
//List of Event Listeners
addBookmarkBtn.addEventListener("click", () => {
categoryName[0].innerText = category.value;
displayOrCloseForm();
});
closeFormBtn.addEventListener("click", () => {
displayOrCloseForm();
});
addBookmarkFormBtn.addEventListener("click", () => {
const bookmarkList = getBookmarks();
const bookmarkObj = {
name: nameInput.value,
category: category.value,
url: urlInput.value
};
if(!nameInput.value.trim() || !urlInput.value.trim()){
alert("Please, provide valid name and URL.");
resetForm();
return;
}
bookmarkList.push(bookmarkObj); // Ajout de l'objet en fin de tableau
localStorage.setItem("bookmarks", JSON.stringify(bookmarkList)); //MAJ du bookmarks dans le localStorage avec le nouvel objet
resetForm();
displayOrCloseForm();
});
viewCategoryBtn.addEventListener("click", () => {
categoryName[1].innerText = category.value;
displayBookmarkList();
displayOrHideCategory();
});
closeListBtn.addEventListener("click", () => {
displayOrHideCategory();
});
deleteBookmarkBtn.addEventListener("click", () => {
const checkedBookmark = document.querySelector('input[name="link-btn"]:checked');
if (!checkedBookmark) return;
const bookmarkList = getBookmarks();
const bookmarkArrIndex = bookmarkList.findIndex(
(bookmark) => bookmark.name === checkedBookmark.id
);
if (bookmarkArrIndex !== -1) {
bookmarkList.splice(bookmarkArrIndex, 1);
//checkedBookmark.parentElement.remove();
localStorage.setItem("bookmarks", JSON.stringify(bookmarkList));
displayBookmarkList();
}
});
<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=0.0">
<title>Bookmark Manager</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<section id="main-section">
<h1>Bookmark Manager</h1>
<div id="dropdown">
<label for="category-dropdown">Select a category:</label>
<select id="category-dropdown" name="options">
<option value="News" selected>News</option>
<option value="Entertainment">Entertainment</option>
<option value="Work">Work</option>
<option value="Miscellaneous">Miscellaneous</option>
</select>
</div>
<div id="buttons">
<button type="button" id="view-category-button">View Category</button>
<button type="button" id="add-bookmark-button">Add Bookmark</button>
</div>
</section>
<section id="form-section" class="hidden">
<form>
<h2 class="category-name"></h2>
<div>
<label for="name">Name:</label>
<input type="text" id="name">
</div>
<div>
<label for="url">URL:</label>
<input type="text" id="url">
</div>
<div>
<button type="button" id="close-form-button">Go Back</button>
<button type="button" id="add-bookmark-button-form">Add Bookmark</button>
</div>
</form>
</section>
<section id="bookmark-list-section" class="hidden">
<h2 class="category-name"></h2>
<div id="category-list">
</div>
<div>
<button type="button" id="close-list-button">Go Back</button>
<button type="button" id="delete-bookmark-button">Delete Bookmark</button>
</div>
</section>
</main>
<script src="script.js"></script>
</body>
</html>
/* file: styles.css */
:root {
--light-grey: #f5f6f7;
--dark-grey: #0a0a23;
--yellow: #f1be32;
--golden-yellow: #feac32;
}
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
main {
display: flex;
justify-content: center;
}
body {
background-color: var(--dark-grey);
}
.hidden {
display: none;
}
section {
display: flex;
flex-direction: column;
justify-content: center;
}
select,
input,
label {
margin-left: 10px;
}
div {
padding: 30px;
display: flex;
justify-content: center;
}
.close-form-button {
background: none;
border: none;
cursor: pointer;
}
h1, h2 {
margin-top: 20px;
text-align: center;
}
#category-list {
text-align: center;
display: flex;
flex-direction: column;
justify-content: flex-start;
background-color: var(--light-grey);
align-self: center;
width: 80%;
margin-top: 15px;
border-radius: 10px;
}
#category-list,
h1,
h2,
label {
color: var(--light-grey);
}
#category-list p {
color: var(--dark-grey);
}
button {
cursor: pointer;
padding: 5px;
width: 100px;
margin: 10px;
color: var(--dark-grey);
background-color: var(--golden-yellow);
background-image: linear-gradient(#fecc4c, #ffac33);
border-color: var(--golden-yellow);
border-width: 3px;
}
button:hover {
background-image: linear-gradient(#ffcc4c, #f89808);
}
section {
margin-top: 60px;
border: 2px solid var(--golden-yellow);
width: fit-content;
border-radius: 10px;
}
Your browser information:
User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Challenge Information:
Build a Bookmark Manager App - Build a Bookmark Manager App

