-1

I am fairly new to javascript, and am working on a note-taking app to practice some things I have learned so far. It all works fine, however, when I click on the Read More button to view overflow text of the note, it displays the text from the most recent note, as opposed to the note I click Read More on. I want the entire text of a particular note to be displayed when its corresponding Read More button is pressed. Am I overthinking this? I think some kind of implementation of for...of, or for loops may help me achieve this outcome. This is a link to my codepen: https://codepen.io/oliverc96/pen/xxdZYrr

const addNote = document.querySelector('.add-note');
const newNote = document.querySelector('#new-note');
const noteFeed = document.querySelector('#note-feed');
let modalBg = document.createElement('div');
let modalWindow = document.createElement('div');
let exitSymbol = document.createElement('i');
let modalText = document.createElement('p');

function expandNote() {
  modalWindow.classList.add('enterAnimation');
  modalBg.style.visibility = 'visible';
  exitSymbol.addEventListener('click', () => {
    modalBg.style.visibility = 'hidden';
    modalWindow.classList.remove('enterAnimation');
  })
}

function createNote() {
  const noteContainer = document.createElement('div');
  noteContainer.classList.add('containerStyle');
  let noteHeader = document.createElement('h1');
  const noteNum = noteFeed.childElementCount;
  noteHeader.innerText = `Note #${noteNum + 1}`;
  noteHeader.classList.add('headerStyle');
  noteContainer.append(noteHeader);
  let noteText = document.createElement('p');
  noteText.innerText = `${newNote.value}`;
  noteText.classList.add('paraStyle');
  noteContainer.append(noteText);
  let readMore = document.createElement('button');
  readMore.innerText = 'Read More';
  readMore.classList.add('btnStyle');
  noteContainer.append(readMore);
  noteFeed.append(noteContainer);
  readMore.addEventListener('click', expandNote);

  modalBg.classList.add('modal-bg');
  modalWindow.classList.add('modal-window');
  exitSymbol.className = 'far fa-times-circle';
  exitSymbol.classList.add('exitSymbol');
  modalWindow.append(exitSymbol);
  modalText.classList.add('fullTextStyle');
  modalText.innerText = `${noteText.innerText}`;
  modalWindow.append(modalText);
  modalBg.append(modalWindow);
  noteContainer.append(modalBg);

  newNote.value = '';
}

addNote.addEventListener('click', createNote);

newNote.addEventListener('keyup', function(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    createNote();
  }
})
Oliver
  • 1
  • 2

1 Answers1

0

Actually your modalText will always store the latest value according to your code. You can follow the following steps to solve this.

  1. Attach an data-attribute to that noteText.
  2. When click on read more pass the id of that specific note.
  3. Now just show the innerText of that selected item. You can use querySelector to get the element using data-attribute.

You can check my implementation.

console.clear();

const addNote = document.querySelector('.add-note');
const newNote = document.querySelector('#new-note');
const noteFeed = document.querySelector('#note-feed');
let modalBg = document.createElement('div');
let modalWindow = document.createElement('div');
let exitSymbol = document.createElement('i');
let modalText = document.createElement('p');

function expandNote(noteContainer, noteNum) {
  return function () {
    modalWindow.classList.add('enterAnimation');
    modalBg.style.visibility = 'visible';
    exitSymbol.addEventListener('click', () => {
      modalBg.style.visibility = 'hidden';
      modalWindow.classList.remove('enterAnimation');
    })
    const data = document.querySelector(`[data-id='${noteNum}']`).innerText;
    showMoreModal(noteContainer, data);
  }
}

function showMoreModal(noteContainer, data) {
  modalBg.classList.add('modal-bg');
  modalWindow.classList.add('modal-window');
  exitSymbol.className = 'far fa-times-circle';
  exitSymbol.classList.add('exitSymbol');
  modalWindow.append(exitSymbol);
  modalText.classList.add('fullTextStyle');
  modalText.innerText = `${data}`;
  modalWindow.append(modalText);
  modalBg.append(modalWindow);
  noteContainer.append(modalBg);
}

function createNote() {
  const noteContainer = document.createElement('div');
  noteContainer.classList.add('containerStyle');
  let noteHeader = document.createElement('h1');
  const noteNum = noteFeed.childElementCount;
  noteHeader.innerText = `Note #${noteNum + 1}`;
  noteHeader.classList.add('headerStyle');
  noteContainer.append(noteHeader);
  let noteText = document.createElement('p');
  noteText.innerText = `${newNote.value}`;
  noteText.classList.add('paraStyle');
  noteText.setAttribute('data-id', noteNum);
  noteContainer.append(noteText);
  let readMore = document.createElement('button');
  readMore.innerText = 'Read More';
  readMore.classList.add('btnStyle');
  noteContainer.append(readMore);
  noteFeed.append(noteContainer);
  readMore.addEventListener('click', expandNote(noteContainer, noteNum));

  newNote.value = '';
}

addNote.addEventListener('click', createNote);

newNote.addEventListener('keyup', function(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    createNote();
  }
})
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-family: 'Montserrat', sans-serif;
}

#wrapper {
  width: 1600px;
  height: 100vh;
  margin: auto;
  text-align: center;
}

h1 {
  font-size: 100px;
  margin-top: 20px;
  font-weight: 500;
}

h2 {
  font-size: 50px;
  font-weight: 400;
  margin-top: 10px;
}

#add-new-note {
  color: rgb(0, 153, 153);
}

textarea {
  width: 1500px;
  margin-top: 30px;
  height: 60px;
  border-radius: 6px;
  padding: 20px;
  font-size: 18px;
}

textarea:focus {
  outline-color: black;
}

.add-note {
  font-size: 20px;
  width: 180px;
  height: 50px;
  border-radius: 6px;
  margin-top: 30px;
  background-color: rgb(0, 153, 153);
  color: white;
  border-style: solid;
  border-color: rgb(0, 102, 102);
}

.add-note:hover {
  background-color: rgb(0, 128, 128);
  cursor: pointer;
}

#note-feed {
  background-color: rgb(0, 153, 153);
  height: 500px;
  margin-top: 25px;
  width: 1500px;
  border-radius: 6px;
  display: flex;
  overflow: scroll;
  flex-wrap: wrap;
  padding: 20px 10px;
  margin-left: 50px;
}

.containerStyle {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  background-color: rgb(169, 169, 214);
  height: 48%;
  width: 31%;
  margin-right: 11px;
  margin-left: 20px;
  border-radius: 6px;
  margin-bottom: 20px;
  overflow: hidden;
  padding: 0 28px;
  padding-bottom: 15px;
  text-align: left;
}

.headerStyle {
  font-size: 30px;
}

.paraStyle {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  font-size: 18px;
  text-overflow: ellipsis;
  overflow: hidden;
}

.btnStyle {
  font-size: 20px;
  width: 150px;
  height: 40px;
  border-radius: 6px;
  background-color: rgb(255, 128, 128);
  color: white;
  border-style: solid;
  border-color: rgb(255, 77, 77);
  align-self: left;

}

.btnStyle:hover {
  background-color: rgb(255, 102, 102);
  cursor: pointer;
}

.modal-bg {
  z-index: 1;
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background: rgba(0,0,0,0.5);
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  visibility: hidden;
  overflow: scroll;
}

.modal-window {
  border-radius: 6px;
  background: white;
  width: 70%;
  min-height: 30%;
  max-height: 70%;
  overflow: scroll;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
}

.enterAnimation {
  animation-name: fadeInDown;
  animation-duration: 1s;
}

@keyframes fadeInDown {
  0% {
    opacity: 0;
    transform: translateY(-200px);
  }
  100% {
    opacity: 1;
  }
}

.exitSymbol {
  color: rgb(0, 128, 128);
  font-size: 30px;
  margin: 20px 20px;
}

.exitSymbol:hover {
  cursor: pointer;
  opacity: 0.8;
}

.fullTextStyle {
  color: black;
  width: 90%;
  height: 80%;
  text-align: left;
  margin-top: 60px;
  margin-bottom: 30px;
  font-size: 18px;
}
<html>

<head>

  <title> Note Taker </title>
  <link type="text/css" href="notes.css" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;500;600;700&display=swap" rel="stylesheet">

</head>

<body>

  <div id="wrapper">

  <h1> Note Taker </h1>

  <h2 id="add-new-note"> Add A New Note: </h2>

  <textarea id="new-note" name="note-box" placeholder="Write your note here"></textarea>

  <button class="add-note"> Add Note </button>

  <div id="note-feed">

  </div>

  </div>

  <script src="notes.js"></script>
  <script src="https://kit.fontawesome.com/6fc6f370ca.js" crossorigin="anonymous"></script>

</body>

</html>
Sifat Haque
  • 5,357
  • 1
  • 16
  • 23
  • Hey man, thanks for the quick response! I tried implementing this into my code, but nothing happens when I click on the Read More button now - the modal window doesn't even show up. Do you have any possible suggestions for why this is happening? modalBg.style.visibility = 'visible'; is set when you click on the Read More button so I don't know why it is not appearing – Oliver Jul 06 '21 at 01:52
  • @Oliver please copy the whole js code from my solution to yours. It should work. – Sifat Haque Jul 06 '21 at 04:56
  • Thank you so much it worked! I must have missed something as I was manually implementing it into my code. I never knew about data attribute tags so that's going to be quite useful information for some of my upcoming projects! – Oliver Jul 06 '21 at 18:30