cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

Quick-add: + add another resource

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

Quick-add: + add another resource

Code Indentation


Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

      <h1>IndexedDB notes demo</h1>

      <section class="note-display">

      <section class="new-note">
        <h2>Enter a new note</h2>
            <label for="title">Note title</label>
            <input id="title" type="text" required>
            <label for="body">Note text</label>
            <input id="body" type="text" required>
            <button>Create new note</button>

      <p>Testing an excercise from
        Mozilla.developer.org. Copyright nobody. Use the code as you like.</p>

              html {
  font-family: sans-serif;

body {
  margin: 0 auto;
  max-width: 800px;

header, footer {
  background-color: rgb(197, 199, 195);
  color: white;
  line-height: 100px;
  padding: 0 20px;

.new-note, .note-display {
  padding: 20px;

.new-note {
  background: #ddd;

h1 {
  margin: 0;

ul {
  list-style-type: none;

div {
  margin-bottom: 10px;

              // Create needed constants Mark Webster wrote all this code
const list = document.querySelector('ul');
const titleInput = document.querySelector('#title');
const bodyInput = document.querySelector('#body');
const form = document.querySelector('form');
const submitBtn = document.querySelector('form button');
//console.log ('script got to line 7');
//create an instance of a db object for storage
let db;
  //console.log ('script got to line 10');
window.onload = function(){
  //open database if it doesnt already exist
  /*open version 1 of notes database*/
  let request = window.indexedDB.open('notes', 1);
  //console.log ('script got to line 15');
  //error handler
  request.onerror = function() {
    console.log('Database failed to open');
  //console.log ('script got to line 20');
  //onsuccess handler
  request.onsuccess = function() {
    console.log('Database opened successfully');

    //store the opened database object in the db variable
    db = request.result;
    //console.log ('script got to line 27');
    //run the displayData() to show notes already in db
  };//end request.onsuccess handler
// $$$$$ script can't get here console.log ('script got to line 31');
  //onupgradeneeded handler
  request.onugradeneeded = function(e) {

    //grab a reference to opened db
    let db = e.target.result;

    /*create an objectStore to store our notes in (single table)
      including an auto-incrementing key*/
    let objectStore = db.createObjectStore('notes', { keyPath: 'id', autoIncrement:true});

    //define what data items objectStore will contain
    objectStore.createIndex('title', 'title', { unique: false });
    objectStore.createIndex('body', 'body', { unique: false });

    console.log('database setup complete');

  //create an onsubmit handler to run the addData() function
  form.onsubmit = addData;

  function addData(e) {
    //prevent Default, don't want to the form to submit in conventional way - causing refresh

    //grab values from form and store them in an object
    let newItem = { title: titleInput.value, body: bodyInput.value };

    //open a read/write db transaction, ready for adding database
    let transaction = db.transaction(['notes'], 'readwrite');

    //call an object store that's already been added to db
    let objectStore = transaction.objectStore('notes');

    //make a request to add our newItem object to the object storage
    var request = objectStore.add(newItem);
    request.onsuccess = function() {
      //clear the form, ready for next entry
      titleInput.value = '';
      bodyInput.value = '';
    };//end request.onsuccess function

    //report on sucess of transaction
    transaction.oncomplete = function(){
      console.log('transaction completed: db mod finished');

      //update display of data to show newly added item

    transaction.onerror = function(){
      console.log('transaction not opened due to error');
  }//end function addData;;;;;?

  function displayData() {
    /*empty the li contents to prevent duplicates
    strips out the fistChild's until there are no more*/
    while (list.firstChild) {//list = the <ul>
      list.removeChild(list.firstChild);// remove <li>'s

    //open our object store and get a cursor - which iterates
    //thru all the different data items in store
    let objectStore = db.transaction('notes').objectStore('notes');
    objectStore.openCursor().onsuccess = function(e) {
      //get a reference to the cursor....cursor????
      let cursor = e.target.result;
      //if there is still another data item to
      //iterate thru keep running this code
      if(cursor) {
        //create a <li>, h3, p
        let listItem = document.createElement('li');
        let h3 = document.createElement('h3');
        let para = document.createElement('p');

        //add <li> to inside of <ul> at bottom below other <li>'s

        //put data from the cursor inside the h3 and para
        h3.textContent = cursor.value.title;
        para.textContent = cursor.value.body;
        //store the ID of the data item inside an atribute
        //on the list item so we know which list item.
        //Will be useful later when we need to delete items
        listItem.setAttribute('data-note-id', cursor.value.id);

        //create a button andn place it in each <li>
        let deleteBtn = document.createElement('button');
        deleteBtn.textContent = 'Delete';

        //set event handler to
        //trigger deleteItem() function to run
        deleteBtn.onclick = deleteItem;

        //iterate to next item in the cursor
        cursor.continue();//this loops the if(true) block
      } else {//when all records are looped thru this runs
        //again, if list item is empty
        if(!list.firstChild) {
          let listItem = document.createElement('li');
          listItem.textContent = 'No notes stored.';//$$$$they don't have ; here
        //if there are no more cursor items to iterate through, say so
        console.log('Notes all displayed');
    };//end objectStore open cursor function
  }//end function display data

  function deleteItem(e) {
    //retrieve name of task to delete, which is currently a string
    //convert it to Number  (IDB key type-sensitive)

    let noteId = Number(e.target.parentNode.getAttribute('data-note-id'));

    ///open a db transaction and use above to find and delete
    let transaction = db.transaction(['notes'], 'readwrite');
    let objectStore = transaction.objectStore('notes');
    let request = objectStore.delete(noteId);

    //report that it's been deleteBtn
    transaction.oncomplete = function() {
      //delete the parent of button
      //which is the <li>
      console.log('Note ' + noteId + ' deleted.');

      //again, if list item is empty
      if(!list.firstChild) {
        let listItem = document.createElement('li');
        listItem.textContent = 'No notes stored.';
    };//end transaction.oncomplete function
  }//end function deleteItem

};//end window.onload

Loading ..................