1

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="bckgrnd-clr" value="white">Background Color</option>
        <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 Update: This is the solution I applied after getting the idea from the comments.

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`
    }

Now this is the error i am getting at color

"Cannot read properties of null (reading 'options')" Any help would be appreciated?

Code_2
  • 23
  • 5

1 Answers1

1

See the working snippet. :)

In your loop, change code like this:

let elm1 = document.getElementById(index)

to

let showNote3 = document.getElementById(`card${index}`);
let colorApply = document.getElementById(`card${index}`)
let elm1 = document.getElementById(`mySelect${index}`)

and in your HTML

`<div class="noteCard my-2 mx-2 card" id="card${index}" ...` />
`<select id=`mySelect${index}` class="clr-btn" style="text-align:center" onchange="change_color()">`

Also when you have the element, you do not need to use document

// -> document.colorApply.style.backgroundColor = color;
colorApply.style.backgroundColor = color;

Finally, you need to send the index of the note into your change_color function.

onchange="change_color(${index})"

function showNote2() {
  console.log("Show");
  let note = null // localStorage.getItem("notes");
  if (note == null) {
    noteData = ['My Note 1', 'My Note 2']
    // 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="card${index}" style="width: 18rem;">
            <select id="mySelect${index}" class="clr-btn" style="text-align:center" onchange="change_color(${index})">
            <option id="bckgrnd-clr" value="white">Background Color</option>
            <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="cardbody${index}">
                      <h5 class="cardtitle">Note ${index + 1}</h5>
                      <p class="card-text"> 
                      ${element}
                      </p>
                      <button id="btn${index}" onclick="deleteNote(this.id)" class="btn btn-primary">Delete Note</a>
                    </div>
                  </div>   
                  `
  })
  let showNote3 = document.getElementById("note");
  if (noteData.length != 0) {
    showNote3.innerHTML = showBox;
  } else {
    showNote3.innerHTML = "Please add a Note"
  }
}

function change_color(index) {
  let note = noteData[index] // localStorage.getItem("notes");
  if (note != null) {
    let colorApply = document.getElementById(`card${index}`)
    let elm1 = document.getElementById(`mySelect${index}`)
    let color = elm1.options[elm1.selectedIndex].value;
    colorApply.style.backgroundColor = color;
  } else {
    console.log(`Note is Empty`)
  }
}

showNote2()
<h1>Notes</h1>
<div id='note' />
<button onclick='note' />
Steven Spungin
  • 27,002
  • 5
  • 88
  • 78
  • Spungin Thanks In this HTML ` – Code_2 Jan 06 '22 at 12:50
  • `function change_color(index) { let note = localStorage.getItem("notes"); if(note != null ){ let colorApply = document.getElementById("card3") let elm1 = document.getElementById(`card${index}`) let color = elm1.options[elm1.selectedIndex].value; document.colorApply.style.backgroundColor = color; } else{ `Note is Empty` }` – Code_2 Jan 06 '22 at 12:50
  • You need to stop hardcoding your IDs. Also, you need to give your select an id to access the options - solution updated with general idea – Steven Spungin Jan 06 '22 at 13:51
  • Got it. Select is updated with ID to access the options Now this is the code that i am using to access the selected option `elm1.options[elm1.selectedIndex].value` but this returns null. Infact it is not null – Code_2 Jan 06 '22 at 14:30
  • use `elm1.value` to get the `select` value. see https://stackoverflow.com/questions/1085801/get-selected-value-in-dropdown-list-using-javascript?rq=1 – Steven Spungin Jan 06 '22 at 15:08
  • I also looked at the question and tried all the answers before posting this one and unfortuantely, `elm1.value` also don't work It gives the same error – Code_2 Jan 06 '22 at 15:39
  • `let elm1 = document.getElementById(\`mySelect${index}\`); console.log(elm1);` If you log it, what does elm1 show? – Steven Spungin Jan 06 '22 at 16:15
  • It gives "null" – Code_2 Jan 06 '22 at 17:53
  • `let showNote3 = document.getElementById(`card${index}`); let colorApply = document.getElementById(`card${index}`) let elm1 = document.getElementById(`mySelect${index}`)` All these codes return "null" – Code_2 Jan 06 '22 at 17:54
  • even (e=event object) returns undefined – Code_2 Jan 06 '22 at 18:02
  • 1
    OK @Code_2. The final issue was you were not sending in an index into your change_color function. I added a working snippet with the fix working. – Steven Spungin Jan 07 '22 at 00:33
  • Thanks, bro it worked Learned something new. I really appreciate YOUR help Next thing I am trying to do is that colors remain the same when the browser is refresh For that, I saved the color value in `local storage` with their `index`. And I called the `index` value at the top of the code so when the browser is refreshed colors remain the same but that didn't work. Everything was back to normal(white). – Code_2 Jan 07 '22 at 08:27
  • 1
    i commented out the local storage calls so the snippet would run in stackoverflow – Steven Spungin Jan 07 '22 at 09:59
  • 1
    makes sense to store [{color:'Red', message:'Hello', modifed:234234}] in one array instead of many. Then add an id field instead of using indexes. :) – Steven Spungin Jan 07 '22 at 10:02
  • noteData = ['My Note 1', 'My Note 2'] Can't get this? Can YOU explain this? – Code_2 Jan 07 '22 at 10:33
  • This is the code i used ` localStorage.setItem(`clr${index}`, color)` this code in change_color function `function backGroundClr(index) { let backclr2 = localStorage.getItem(`clr${index}`) colorApply.style.backgroundColor = backclr2 console.log(backGroundClr) }` – Code_2 Jan 07 '22 at 10:35
  • open up another issue for this @code2 – Steven Spungin Jan 07 '22 at 14:40
  • Hello @Steven The answer YOU proposed works great but one issue is still there that it these code return me null ```let showNote3 = document.getElementById(card${index}); let colorApply = document.getElementById(card${index}) let elm1 = document.getElementById(mySelect${index})``` These are returning Null which is causing issue while making another function. Any idea about this? – Code_2 Jan 13 '22 at 06:57