Spaces:
Running
Running
File size: 9,359 Bytes
8196597 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
// Create needed constants
const list = document.querySelector('ul');
const titleInput = document.querySelector('#title');
const dateInput = document.querySelector('#date');
const contentInput = document.querySelector('#content');
const form = document.querySelector('form');
const newBtn = document.querySelector('#newBtn');
// Create an instance of a db object for us to store the open database in
let db;
// Open our database; it is created if it doesn't already exist
// (see the upgradeneeded handler below)
const openRequest = window.indexedDB.open("notes_db", 1);
// error handler signifies that the database didn't open successfully
openRequest.addEventListener("error", () => console.error("Database failed to open"));
// Create a submit event handler so that when the form is submitted the addData() function is run
form.addEventListener("submit", addData);
// success handler signifies that the database opened successfully
openRequest.addEventListener("success", () => {
console.log("Database opened successfully");
// Store the opened database object in the db variable.
// This is used a lot below.
db = openRequest.result;
// Run the displayData() function to display the notes already in the IDB
displayData();
});
// Finally for this section, we'll add probably the most important event
// handler for setting up the database: upgradeneeded. This handler runs if the
// database has not already been set up, or if the database is opened with a
// bigger version number than the existing stored database (when performing an
// upgrade). Add the following code, below your previous handler:
// Set up the database tables if this has not already been done.
// Here we first grab a reference to the existing database from the result
// property of the event's target (e.target.result), which is the request
// object. This is equivalent to the line db = openRequest.result; inside the
// success event handler, but we need to do this separately here because the
// upgradeneeded event handler (if needed) will run before the success event
// handler, meaning that the db value wouldn't be available if we didn't do
// this.
openRequest.addEventListener("upgradeneeded", (e) => {
// Grab a reference to the opened database
db = e.target.result;
// Create an objectStore in our database to store notes and an
// auto-incrementing key
// An objectStore is similar to a 'table' in a relational database
const objectStore = db.createObjectStore("notes_os", {
keyPath: "id",
autoIncrement: true,
});
// Define what data items the objectStore will contain
objectStore.createIndex("title", "title", { unique: false });
objectStore.createIndex("content", "content", { unique: false });
objectStore.createIndex("date", "date", { unique: false });
// Print the outcome of the setup
console.log("Database setup completed.");
});
// Define the addData() function
function addData(e) {
// prevent default - we don't want the form to submit in the conventional way
e.preventDefault();
// grab the values entered into the form fields and store them in an object ready for being inserted into the DB
const newItem = {
title: titleInput.value,
content: contentInput.value,
date: dateInput.value
};
// open a read/write db transaction, ready for adding the data,
// name of the db: notes_os
// IDBDatabase.transaction()
const transaction = db.transaction(["notes_os"], "readwrite");
// call an object store that's already been added to the database
// IDBTransaction.objectStore()
const objectStore = transaction.objectStore("notes_os");
// Make a request to add our newItem object to the object store
// IDBObjectStore.add()
const addRequest = objectStore.add(newItem);
// If the transaction is successful
addRequest.addEventListener("success", () => {
// Clear the form, ready for adding the next entry
titleInput.value = "";
contentInput.value = "";
dateInput.value = "";
});
// Report on the success of the transaction completing, when everything is done
transaction.addEventListener("complete", () => {
console.log("Transaction completed: database modification finished.");
// update the display of data to show the newly added item, by running displayData() again.
displayData();
});
// If there is error in the transaction
transaction.addEventListener("error", () => console.log("Transaction not opened due to error"));
}
// Define the displayData() function
function displayData() {
// Here we empty the contents of the list element each time the display is updated
// If you didn't do this, you'd get duplicates listed each time a new note is added
while (list.firstChild) {
list.removeChild(list.firstChild);
}
// Open our object store and then get a cursor - which iterates through all the
// different data items in the store
const transaction = db.transaction("notes_os");
const objectStore = transaction.objectStore("notes_os");
// IDBObjectStore: openCursor(). Returns an IDBRequest object, and, in a
// separate thread, returns a new IDBCursorWithValue object. Used for
// iterating through an object store with a cursor.
objectStore.openCursor().addEventListener("success", (e) => {
// Get a reference to the cursor
const cursor = e.target.result;
// If there is still another data item to iterate through, keep running this code,
// In short:
// if (cursor) {
// cursor.value contains the current record being iterated through
// this is where you'd do something with the result
// cursor.continue();
//}
// else {
// no more results
//}
if (cursor) {
// Create a list item, h3, and p to put each data item inside when displaying it
// structure the HTML fragment, and append it inside the list
const listItem = document.createElement("li");
const h3 = document.createElement("h3");
const para = document.createElement("p");
listItem.appendChild(h3);
listItem.appendChild(para);
list.appendChild(listItem);
// Put the data from the cursor inside the h3 and para
h3.textContent = cursor.value.title;
para.textContent = `${cursor.value.date}: ${cursor.value.content}`;
// Store the ID of the data item inside an attribute on the listItem, so we know
// which item it corresponds to. This will be useful later when we want to delete items
listItem.setAttribute("data-note-id", cursor.value.id);
// Create a button and place it inside each listItem
const deleteBtn = document.createElement("button");
listItem.appendChild(deleteBtn);
deleteBtn.textContent = "Delete";
// Set an event handler so that when the button is clicked, the deleteItem()
// function is run
deleteBtn.addEventListener("click", deleteItem);
// Iterate to the next item in the cursor
cursor.continue();
}
else {
// Again, if list item is empty, display a 'No notes stored' message
if (!list.firstChild) {
const listItem = document.createElement("li");
listItem.textContent = "No notes stored.";
list.appendChild(listItem);
}
// if there are no more cursor items to iterate through, say so
console.log("Notes all displayed");
}
});
}
// Define the deleteItem() function
function deleteItem(e) {
// retrieve the name of the task we want to delete. We need
// to convert it to a number before trying to use it with IDB; IDB key
// values are type-sensitive.
const ulNode = e.target.parentNode;
// const noteId = Number(e.target.parentNode.getAttribute("data-note-id"));
// We do however need to pass the attribute through the global built-in
// Number() object as it is of datatype string, and therefore wouldn't be
// recognized by the database, which expects a number.
const noteId = Number(ulNode.getAttribute("data-note-id"));
// open a database transaction and delete the task, finding it using the id we retrieved above
const transaction = db.transaction(["notes_os"], "readwrite");
const objectStore = transaction.objectStore("notes_os");
const deleteRequest = objectStore.delete(noteId);
// report that the data item has been deleted
transaction.addEventListener("complete", () => {
// delete the parent of the button
// which is the list item, so it is no longer displayed
//e.target.parentNode.parentNode.removeChild(e.target.parentNode);
ulNode.parentNode.removeChild(ulNode);
console.log(`Note ${noteId} deleted.`);
// Again, if list item is empty, display a 'No notes stored' message
if (!list.firstChild) {
const listItem = document.createElement("li");
listItem.textContent = "No notes stored.";
list.appendChild(listItem);
}
});
}
|