Added book adding, README, modified looks
This commit is contained in:
parent
ce59d1b051
commit
6a73665b98
|
@ -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)
|
Binary file not shown.
After Width: | Height: | Size: 237 KiB |
20
index.html
20
index.html
|
@ -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" />
|
<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>
|
</head>
|
||||||
<body>
|
<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>
|
<header>
|
||||||
<h1>boocks</h1>
|
<h1>boocks</h1>
|
||||||
|
<button type="button" id="new-book">
|
||||||
|
<i class="fa-solid fa-plus"></i> New book
|
||||||
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<div id="books">
|
<div id="books">
|
||||||
|
|
||||||
|
|
176
script.js
176
script.js
|
@ -9,92 +9,128 @@ function Book(title, author, pages, read) {
|
||||||
this.read = read;
|
this.read = read;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addBookToLibrary(book) {
|
function addBookToLibrary(title, author, pages, read) {
|
||||||
library.push(book);
|
let bookObject = new Book(title, author, pages, read);
|
||||||
|
library.push(bookObject);
|
||||||
|
displayBooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function removeBookFromLibrary(dataId) {
|
||||||
|
library.splice(dataId, 1);
|
||||||
|
displayBooks();
|
||||||
}
|
}
|
||||||
|
|
||||||
let books = [
|
let books = [
|
||||||
["book", "author", 1, true],
|
["The Hobbit", "J.R.R. Tolkien", 295, false],
|
||||||
["book", "author", 1, true],
|
["Jessica's Guide to Dating on the Dark Side", "Natalie M. Pete-Clarkson Jr.", 295, false],
|
||||||
["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],
|
|
||||||
]
|
]
|
||||||
|
|
||||||
books.forEach(book => {
|
if (books.length) {
|
||||||
let aBook = new Book(book[0], book[1], book[2], book[3]);
|
books.forEach(book => {
|
||||||
addBookToLibrary(aBook);
|
addBookToLibrary(book[0], book[1], book[2], book[3]);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
displayBooks();
|
displayBooks();
|
||||||
})
|
}
|
||||||
|
|
||||||
|
|
||||||
function displayBooks() {
|
function displayBooks() {
|
||||||
bookGrid.querySelectorAll("& > *").forEach(book => {
|
bookGrid.querySelectorAll("& > *").forEach(book => {
|
||||||
book.remove();
|
book.remove();
|
||||||
})
|
})
|
||||||
let pos = 0;
|
let dataId = 0;
|
||||||
library.forEach(book => {
|
if (library.length) {
|
||||||
bookDiv = document.createElement("div");
|
library.forEach(book => {
|
||||||
bookDiv.classList.add("book");
|
let bookDiv = document.createElement("div");
|
||||||
bookDiv.setAttribute("arrayPos", pos)
|
bookDiv.classList.add("book");
|
||||||
|
bookDiv.setAttribute("data-id", dataId)
|
||||||
|
|
||||||
bookDetails = document.createElement("div");
|
let bookDetails = document.createElement("div");
|
||||||
bookDetails.classList.add("book-details");
|
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);
|
|
||||||
|
|
||||||
bookActions = document.createElement("div");
|
let allDetails = {
|
||||||
bookActions.classList.add("book-actions");
|
"title": `${book.title}`,
|
||||||
|
"author": `${book.author}`,
|
||||||
toggleRead = document.createElement("i");
|
"pages": `${book.pages}`,
|
||||||
toggleRead.classList.add("fa-solid", "fa-book");
|
"status": `${book.read ? "read" : "not read yet"}`,
|
||||||
toggleRead.addEventListener("click", function() {
|
};
|
||||||
library[this.parentNode.parentNode.getAttribute("arrayPos")].read = !library[this.parentNode.parentNode.getAttribute("arrayPos")].read;
|
|
||||||
displayBooks();
|
|
||||||
});
|
|
||||||
bookActions.append(toggleRead);
|
|
||||||
|
|
||||||
edit = document.createElement("i");
|
for (detail in allDetails) {
|
||||||
edit.classList.add("fa-solid", "fa-edit");
|
let detailNameContain = document.createElement("div");
|
||||||
edit.addEventListener("click", function() {
|
detailNameContain.classList.add("detail-name");
|
||||||
library.splice(this.parentNode.parentNode.getAttribute("arrayPos"), 1);
|
|
||||||
displayBooks();
|
|
||||||
});
|
|
||||||
bookActions.append(edit);
|
|
||||||
|
|
||||||
removeBtn = document.createElement("i");
|
let detailName = document.createElement("span");
|
||||||
removeBtn.classList.add("fa-solid", "fa-trash");
|
detailName.textContent = `${detail}: `;
|
||||||
removeBtn.addEventListener("click", function() {
|
detailNameContain.append(detailName);
|
||||||
library.splice(this.parentNode.parentNode.getAttribute("arrayPos"), 1);
|
|
||||||
displayBooks();
|
|
||||||
});
|
|
||||||
bookActions.append(removeBtn);
|
|
||||||
|
|
||||||
bookDiv.append(bookActions);
|
let detailContent = document.createElement("span");
|
||||||
|
detailContent.textContent = allDetails[detail];
|
||||||
|
detailContent.classList.add("detail-content");
|
||||||
|
|
||||||
bookGrid.append(bookDiv);
|
bookDetails.append(detailNameContain, detailContent);
|
||||||
pos++;
|
};
|
||||||
})
|
|
||||||
|
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 newBookBtn = document.querySelector("button#new-book");
|
||||||
// const newBookDialog = document.querySelector("dialog#new-book");
|
const newBookDialog = document.querySelector("dialog");
|
||||||
// newBookBtn.addEventListener("click", () => {
|
newBookBtn.addEventListener("click", () => {
|
||||||
// newBookDialog.showModal();
|
newBookDialog.showModal();
|
||||||
// })
|
})
|
||||||
// newBookDialog.querySelector("button[type='submit']").addEventListener("click", () => {
|
|
||||||
// let names = [];
|
newBookDialog.querySelector("form").addEventListener("submit", (event) => {
|
||||||
// newBookDialog.querySelectorAll("form > input").forEach(input => {
|
let formData = new FormData(document.querySelector("form"));
|
||||||
// if (!names.includes(input.name)) {
|
let bookVals = []
|
||||||
// names.push(input.name);
|
for (let [key, value] of formData.entries()) {
|
||||||
// }
|
bookVals.push(value);
|
||||||
// });
|
}
|
||||||
// names.forEach(one => {
|
addBookToLibrary(bookVals[0], bookVals[1], bookVals[2], bookVals[3]);
|
||||||
// document.getElementsByName(one).value = "";
|
});
|
||||||
// })
|
|
||||||
// })
|
newBookDialog.addEventListener("close", (event) => {
|
||||||
|
newBookDialog.querySelectorAll("input").forEach(input => {
|
||||||
|
input.value = null;
|
||||||
|
})
|
||||||
|
newBookDialog.querySelector("input[type='radio']").checked = true;
|
||||||
|
});
|
92
style.css
92
style.css
|
@ -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');
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap');
|
||||||
|
|
||||||
:root {
|
: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 {
|
html, body {
|
||||||
|
@ -18,35 +18,73 @@ header {
|
||||||
padding: 20px 40px;
|
padding: 20px 40px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
font-weight: bold;
|
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 {
|
#books {
|
||||||
display: grid;
|
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;
|
gap: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
|
||||||
|
.no-books {
|
||||||
|
font-size: 2rem;
|
||||||
|
text-shadow: 1px 1px 1px #2222dddd;
|
||||||
|
}
|
||||||
|
|
||||||
.book {
|
.book {
|
||||||
background-color: #1d1d1dcc;
|
background-color: #1d1d1dcc;
|
||||||
padding: 30px;
|
padding: 20px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
.book-details {
|
.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 {
|
.book-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
justify-content: flex-end;
|
justify-content: center;
|
||||||
i {
|
i {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
@ -79,12 +117,12 @@ header {
|
||||||
.fa-book::after {
|
.fa-book::after {
|
||||||
content: "toggle read";
|
content: "toggle read";
|
||||||
}
|
}
|
||||||
.fa-edit:hover {
|
/* .fa-edit:hover {
|
||||||
color: rgb(219, 175, 30);
|
color: rgb(219, 175, 30);
|
||||||
}
|
}
|
||||||
.fa-edit::after {
|
.fa-edit::after {
|
||||||
content: "edit";
|
content: "edit";
|
||||||
}
|
} */
|
||||||
.fa-trash:hover {
|
.fa-trash:hover {
|
||||||
color: rgb(220, 85, 85);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue