Search code examples
javascriptjsonformslocal-storage

Trouble saving and displaying form submission data to localStorage


I am trying to create a basic script that takes information from an HTML form and displays it on the page. This project is just to practice the JavaScript functions that I am currently learning through self-study.

Right now submitting the form creates a card on the page that displays the information submitted, and each time the form is submitted a new card is created. However, the challenge I am facing now is that when the page is refreshed, all of the cards disappear.

I am trying to figure out how to use localStorage and have added some basic functions to my code; however I am finding that the cards still disappear when the page is refreshed. My questions are:

  1. How can I check whether the data from the form submission is actually being saved somewhere?
  2. How can I edit my code to continue to display the existing cards on the page even when the page is refreshed?

Here is my code on CodePen.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flashcard Project</title>
    <link rel="stylesheet" href="./flashcard_styles.css">
</head>
<body>
    <div class="form-wrapper">
        <h1 class="form-title">Add a word</h1>
        <form id="vocab-form" method="POST">
            <div class="input-group">
                <label for="word">Word</label>
                <input id="word" name="word" type="text" placeholder="詞彙">
            </div>
            <div class="input-group">
                <label for="meaning">Meaning</label>
                <input id="meaning" name="meaning" type="text" placeholder="vocabulary">
            </div>
            <div class="input-group">
                <label for="notes">Notes</label>
                <textarea id="notes" name="notes" rows="6" cols="30"></textarea>
            </div>
            <button id="submit" type="submit" value="submit">Add</button>
        </form>
    </div>
    <div class="vocab-grid">
    </div>

    <script src="./flashcard_script.js"></script>
</body>
</html>
const myVocab = [];

function saveData() {
    localStorage.setItem('myVocab', JSON.stringify(myVocab));
}

function loadData() {
    const storedData = localStorage.getItem('myVocab');
    if(storedData) {
        myVocab.push(...JSON.parse(storedData));
    }
}

loadData();

const form = document.querySelector('form');
const vocabGrid = document.querySelector('.vocab-grid');

// define a constructor function to create vocab objects
function Vocab(word, meaning, notes) {
    this.word = word;
    this.meaning = meaning;
    this.notes = notes;
}

// define a function to add new Vocab to myVocab on form submit click
function addVocab(event) {
    event.preventDefault();

    const data = new FormData(event.target);

    let formObj = {}; // initialize empty object to store form values

    // loop thru FormData entried
    for(let [key, value] of data.entries()) {
        formObj[key] = value; // stores the values with their keys within the formObj object
    }

    // convert the stored formObj to a more useful newVocab object, using the constructor function created above
    const newVocab = new Vocab(formObj.word, formObj.meaning, formObj.notes);
    
    myVocab.push(newVocab);

    // clear form after submission
    event.target.reset();

    // save the form submission data to localStorage
    saveData();

    return newVocab;
}

// this function will run every time the submit button is clicked
form.addEventListener('submit', function(event) {

    // first, call the addVocab function, store its result in a new variable
    const addedVocab = addVocab(event);

    // second, create the DOM elements needed to display the vocab on a card
    const newVocabCard = document.createElement('div');
    newVocabCard.classList.add('vocab-card');
    newVocabCard.style.cssText = `
        padding: 10px;
        border: 3px solid black;
        color: var(--drkPurple);
        background-color: white;
        border-radius: 5px;
        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);`

    const vocabWord = document.createElement('p');
    vocabWord.innerText = addedVocab.word;

    const vocabMeaning = document.createElement('p');
    vocabMeaning.innerText = addedVocab.meaning;

    const vocabNotes = document.createElement('p');
    vocabNotes.innerText = addedVocab.notes;

    newVocabCard.appendChild(vocabWord);
    newVocabCard.appendChild(vocabMeaning);
    newVocabCard.appendChild(vocabNotes);

    vocabGrid.appendChild(newVocabCard);
});

I am a total JavaScript beginner and this is my first time trying to use an API so the simplest way to solve this would be best for my learning! Thanks in advance!


Solution

  • Your data is being saved to localStorage - I verified with the dev tools on your codepen. The issue is you have no code to generate the cards on page load.

    What I would suggest is creating a function that accepts a vocab object, and adds a corresponding card to the dom (similar to the code you have in your submit listener).

    Up where you call loadData you would then loop over the vocab array and call that function for each item in the array. You can also use this new function in your submit handler to reduce code duplication. Does that make sense?