Added book adding, README, modified looks

This commit is contained in:
NetMan 2024-01-28 19:29:16 +01:00
parent ce59d1b051
commit 6a73665b98
6 changed files with 224 additions and 79 deletions

15
README.md Normal file
View File

@ -0,0 +1,15 @@
# odin-library
A simple book tracking site using vanilla HTML CSS JS
boocks - book/tracks
### todo:
* save library to cookies / localstorage
* edit existing books
## pics
![Alt text](image.png)
![Alt text](image-1.png)

BIN
image-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

BIN
image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View File

@ -10,8 +10,28 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
<dialog>
<form method="dialog" id="form">
<section><label for="title">title: </label> <input type="text" name="title" id="title" required></section>
<section><label for="author">author: </label> <input type="text" name="author" id="author" required></section>
<section><label for="pages">pages: </label> <input type="number" name="pages" id="pages" required></section>
<section>
<label for="">status: </label>
<input type="radio" name="status" id="yes" value="true" required checked>
<label for="yes">Read</label>
<input type="radio" name="status" id="no" value="false">
<label for="no">Not read yet</label>
</section>
<section>
<button type="submit">Add book</button>
</section>
</form>
</dialog>
<header>
<h1>boocks</h1>
<button type="button" id="new-book">
<i class="fa-solid fa-plus"></i> New book
</button>
</header>
<div id="books">

176
script.js
View File

@ -9,92 +9,128 @@ function Book(title, author, pages, read) {
this.read = read;
}
function addBookToLibrary(book) {
library.push(book);
function addBookToLibrary(title, author, pages, read) {
let bookObject = new Book(title, author, pages, read);
library.push(bookObject);
displayBooks();
}
function removeBookFromLibrary(dataId) {
library.splice(dataId, 1);
displayBooks();
}
let books = [
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["book", "author", 1, true],
["The Hobbit", "J.R.R. Tolkien", 295, false],
["Jessica's Guide to Dating on the Dark Side", "Natalie M. Pete-Clarkson Jr.", 295, false],
]
books.forEach(book => {
let aBook = new Book(book[0], book[1], book[2], book[3]);
addBookToLibrary(aBook);
if (books.length) {
books.forEach(book => {
addBookToLibrary(book[0], book[1], book[2], book[3]);
})
} else {
displayBooks();
})
}
function displayBooks() {
bookGrid.querySelectorAll("& > *").forEach(book => {
book.remove();
})
let pos = 0;
library.forEach(book => {
bookDiv = document.createElement("div");
bookDiv.classList.add("book");
bookDiv.setAttribute("arrayPos", pos)
let dataId = 0;
if (library.length) {
library.forEach(book => {
let bookDiv = document.createElement("div");
bookDiv.classList.add("book");
bookDiv.setAttribute("data-id", dataId)
bookDetails = document.createElement("div");
bookDetails.classList.add("book-details");
bookDetails.innerText = `${book.title}\n${book.author}\n${book.pages} pages\n${book.read ? "read" : "not read yet"}`;
bookDiv.append(bookDetails);
let bookDetails = document.createElement("div");
bookDetails.classList.add("book-details");
bookActions = document.createElement("div");
bookActions.classList.add("book-actions");
toggleRead = document.createElement("i");
toggleRead.classList.add("fa-solid", "fa-book");
toggleRead.addEventListener("click", function() {
library[this.parentNode.parentNode.getAttribute("arrayPos")].read = !library[this.parentNode.parentNode.getAttribute("arrayPos")].read;
displayBooks();
});
bookActions.append(toggleRead);
let allDetails = {
"title": `${book.title}`,
"author": `${book.author}`,
"pages": `${book.pages}`,
"status": `${book.read ? "read" : "not read yet"}`,
};
edit = document.createElement("i");
edit.classList.add("fa-solid", "fa-edit");
edit.addEventListener("click", function() {
library.splice(this.parentNode.parentNode.getAttribute("arrayPos"), 1);
displayBooks();
});
bookActions.append(edit);
for (detail in allDetails) {
let detailNameContain = document.createElement("div");
detailNameContain.classList.add("detail-name");
removeBtn = document.createElement("i");
removeBtn.classList.add("fa-solid", "fa-trash");
removeBtn.addEventListener("click", function() {
library.splice(this.parentNode.parentNode.getAttribute("arrayPos"), 1);
displayBooks();
});
bookActions.append(removeBtn);
let detailName = document.createElement("span");
detailName.textContent = `${detail}: `;
detailNameContain.append(detailName);
bookDiv.append(bookActions);
let detailContent = document.createElement("span");
detailContent.textContent = allDetails[detail];
detailContent.classList.add("detail-content");
bookGrid.append(bookDiv);
pos++;
})
bookDetails.append(detailNameContain, detailContent);
};
bookDiv.append(bookDetails);
let bookActions = document.createElement("div");
bookActions.classList.add("book-actions");
let toggleRead = document.createElement("i");
toggleRead.classList.add("fa-solid", "fa-book");
toggleRead.addEventListener("click", function() {
library[this.parentNode.parentNode.getAttribute("data-id")].read = !library[this.parentNode.parentNode.getAttribute("data-id")].read;
displayBooks();
});
bookActions.append(toggleRead);
// let edit = document.createElement("i");
// edit.classList.add("fa-solid", "fa-edit");
// edit.addEventListener("click", function() {
// removeBookFromLibrary(this.parentNode.parentNode.getAttribute("data-id"));
// });
// bookActions.append(edit);
let removeBtn = document.createElement("i");
removeBtn.classList.add("fa-solid", "fa-trash");
removeBtn.addEventListener("click", function() {
removeBookFromLibrary(this.parentNode.parentNode.getAttribute("data-id"));
});
bookActions.append(removeBtn);
bookDiv.append(bookActions);
bookGrid.append(bookDiv);
dataId++;
})
} else {
let info = document.createElement("span");
info.classList.add("no-books");
info.textContent = "No books to list. Add some!";
bookGrid.append(info);
}
}
// const newBookBtn = document.querySelector("button#new-book");
// const newBookDialog = document.querySelector("dialog#new-book");
// newBookBtn.addEventListener("click", () => {
// newBookDialog.showModal();
// })
// newBookDialog.querySelector("button[type='submit']").addEventListener("click", () => {
// let names = [];
// newBookDialog.querySelectorAll("form > input").forEach(input => {
// if (!names.includes(input.name)) {
// names.push(input.name);
// }
// });
// names.forEach(one => {
// document.getElementsByName(one).value = "";
// })
// })
const newBookBtn = document.querySelector("button#new-book");
const newBookDialog = document.querySelector("dialog");
newBookBtn.addEventListener("click", () => {
newBookDialog.showModal();
})
newBookDialog.querySelector("form").addEventListener("submit", (event) => {
let formData = new FormData(document.querySelector("form"));
let bookVals = []
for (let [key, value] of formData.entries()) {
bookVals.push(value);
}
addBookToLibrary(bookVals[0], bookVals[1], bookVals[2], bookVals[3]);
});
newBookDialog.addEventListener("close", (event) => {
newBookDialog.querySelectorAll("input").forEach(input => {
input.value = null;
})
newBookDialog.querySelector("input[type='radio']").checked = true;
});

View File

@ -1,7 +1,7 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap');
:root {
font-family: 'Roboto', sans-serif;
font-family: "Roboto", system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
html, body {
@ -18,35 +18,73 @@ header {
padding: 20px 40px;
box-sizing: border-box;
text-align: center;
display: flex;
justify-content: space-between;
h1 {
font-size: 2.5rem;
font-weight: bold;
}
button#new-book {
font-size: 1rem;
font-weight: bold;
border: 2px solid #444;
color: #fff;
background-color: #232323;
cursor: pointer;
outline: none;
border-radius: 15px;
padding: 5px 10px;
}
}
#books {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(max(20%, 270px), 1fr));
grid-template-columns: repeat(auto-fill, minmax(max(20%, 270px), 1fr));
gap: 20px;
padding: 20px;
.no-books {
font-size: 2rem;
text-shadow: 1px 1px 1px #2222dddd;
}
.book {
background-color: #1d1d1dcc;
padding: 30px;
padding: 20px;
border-radius: 20px;
font-size: 1.3rem;
text-align: center;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 10px;
.book-details {
margin: auto;
flex: 1;
display: grid;
align-items: stretch;
grid-template-columns: 50px 1fr;
& > span {
display: block;
padding: 4px;
word-break: break-word;
}
span ~ span, .detail-name ~ .detail-name {
border-top: 1px solid #aaaaaaaa;
}
.detail-name {
color: #aaa;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
}
}
.book-actions {
display: flex;
flex-direction: column;
gap: 8px;
justify-content: flex-end;
justify-content: center;
i {
display: block;
font-size: 1.2rem;
@ -79,12 +117,12 @@ header {
.fa-book::after {
content: "toggle read";
}
.fa-edit:hover {
/* .fa-edit:hover {
color: rgb(219, 175, 30);
}
.fa-edit::after {
content: "edit";
}
} */
.fa-trash:hover {
color: rgb(220, 85, 85);
}
@ -93,4 +131,40 @@ header {
}
}
}
}
}
dialog {
background-color: #000000aa;
padding: 50px 40px;
color: #fff;
&[open] ~ * {
filter: blur(6px);
}
section {
display: flex;
justify-content: space-between;
gap: 5px;
padding: 5px;
align-items: center;
input[type="text"], input[type="number"] {
padding: 5px;
border-radius: 10px;
background-color: #121212aa;
outline: none;
border: 1px solid #aaaaaaaa;
color: #fff;
}
button[type="submit"] {
padding: 5px;
border-radius: 10px;
background-color: #121212aa;
outline: none;
border: 1px solid #aaaaaaaa;
color: #fff;
font-size: 1rem;
cursor: pointer;
margin: auto;
}
}
}