JavaScript: Select different background color of each element from different color

I have a project which is the note-taking website. When someone adds a note it is stored in local storage in the form of an array and a Javascript function works which calls the stored element and runs for each on the elements. Here is the Javascript code:

function showNote2() {
    console.log("Show");
    let note = localStorage.getItem("notes");
    if(note == null){
        noteData = []
        // message.innerText = "Please Add a Note"
    }
    else{
        noteData = JSON.parse(note);
    };
    let showBox = "";
    noteData.forEach(function show(element, index) {
        showBox += `<div class="noteCard my-2 mx-2 card" id="card4" style="width: 18rem;">
        <select id="mySelect" class="clr-btn" style="text-align:center" onchange="change_color()">
        <option id="red" value="Red">Red</option>
        <option id="green" value="Green">Green</option>
        <option id="blue" value="Blue">Blue</option>
        </select>
                <div class="card-body" id="card3">
                  <h5 class="cardtitle">Note
                  ${index + 1}
                  </h5>
                  <p class="card-text"> 
                  ${element}
                  </p>
                  <button id="${index}" onclick="deleteNote(this.id)" class="btn btn-primary">Delete Note</a>
                </div>
              </div>   `
            })
              let showNote3 = document.getElementById("notes2");
              if(noteData.length != 0){
                  showNote3.innerHTML = showBox;
              }else{
                  showNote3.innerHTML = "Please add a Note"
              }
}

In the above code, select gives us the option to choose a color for the note, now I want to add a function to onchange which can help me choose a different color for different notes. The function I used was working only on the first-note and setting the color of all notes according to the selected option of first-note. The color will be applied on class with card-body

I am building this for practice in Javascript. Any hints would be appreciated, as this is something new for me

I think it’s great that your having a play around with vanilla JS :slightly_smiling_face:

Usually when you store data you store it as an object e.g.

let notes = {
note1: { title: "Important Reminder", message: "Pay phone bill", colour: "red"}, 
note2: {another: 'note'}
}

and iterate objects eg.

for(let [key, obj] of Object.entries(notes)){
let content = `<div class = 'parent' style = 'background-color : ${obj.colour} data-id = '${key}'>
<h3>${obj.title}</h3>
<p> ${obj.message}</p>
</div>`
elements[i].innerHTML = content;

It would probably be easier to put your values inside your template string like above.

But if your super worried about XSS ect you can always do

document.createElement(documentFragment);
forEach() // createElement(), element.textContent = title ect, docFrag.appendChild(el)

(BTW, just above is pseudo code, it wont work as is :slightly_smiling_face:)

Also if you are using custom-elements you can attach your event listeners to connectedCallback()

You could use a button on each card to change the colour or on the right click but right click wouldn’t work on mobile.

If you attach the object key to the element e.g. data-id = ${key} you can then use the element.dataset.id to access the stored object and update the colour in localStorage

1 Like

Thanks @steve.mills Got it
But i applied this solution and i am getting this error. Can YOU please also have a look at this:
function change_color(index) { let note = localStorage.getItem("notes"); if(note != null ){ let colorApply = document.getElementById("card3") let elm1 = document.getElementById(index) let color = elm1.options[elm1.selectedIndex].value; document.colorApply.style.backgroundColor = color; } else{ Note is Empty }
The error i am getting is:

“Cannot read properties of null (reading ‘options’)” Any help would be appreciated?

When either selecting JS objects or DOM elements you can only access properties that the object or element has.

The request event object from fetch will usually have e.g. url: "index.html", "method: 'GET', mode: 'navigate' so you could access the method by event.request.method.

HTML Elements usually have id, class, style ect and if you define a data-property you can access it by element.dataset.property.

If you want to work out what properties an object has just log it to the console e.g. console.log(elm1).

I think this is what your trying to do

const changeColor = function (cardId) {
    let selectedColor;
    let notes = localStorage.getItem('notes');
    let card = document.getElementById(cardId);
    let objId = card.dataset.id;
    let selectEl = card.querySelector('select');
    let nodes = selectEl.children;
    for (let option of nodes) {
        if (option.selected == 'true') {
            selectedColor = option.value;
            card.style.backgroundColor = selectedColor;
            break
        }
        else continue
    }
    if (selectedColor) {
        let notesObj = JSON.parse(notes);
        let cardObj = notesObj[objId];
        if (cardObj) cardObj.color = cardColor;
        localStorage.setItem('notes', JSON.stringify(notesObj))
    }
}
1 Like

Thanks @steve.mills

1 Like