skip to Main Content

I am trying to retrieve the properties of each person by clicking their respective name button within another div. However, I am unsure how to establish a connection between the objects inside infos and the buttons so that my loop can identify which button corresponds to which object.

const app = document.querySelector('.app')
const names = Array.from(document.querySelectorAll('.names div'));
const activeName = document.querySelector('.current-name')

const infos = [
  {
    fullName: 'Yassir Lasfar',
    age: 17,
    favSong: 'Way Down We Go'
  },
  {
    fullName: 'Imane Lasfar',
    age: 10,
    favSong: 'Mamamia'
  },
  {
    fullName: 'Khalil Belajmia',
    age: 18,
    favSong: 'Half A Man'
  }
]


for (let name of names) {
  name.addEventListener('click', () => {
    infos.forEach(info => {
      activeName.innerHTML =
        `
            <div class="full-name">Name: ${info.fullName}</div>
                <div class="active-age">Age : ${info.age}</div>
                <div class="favourite-song">Favourite song : ${info.favSong}</div>
            `
    })
  })
}
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

.app {
  border: 2px solid black;
  display: flex;
  flex-direction: row;
  width: 500px;
  align-items: center;
  justify-content: center;
  margin: 100px;
}

.current-name {
  border: 2px solid black;
  width: 250px;
  margin: 20px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

.names {
  margin: 20px;
  border: 2px solid black;
  /* height: ; */
  padding: 20px;
}

.names div {
  border: 1px solid black;
  margin: 5px;
  padding: 10px;
  font-weight: 700;
  background-color: aqua;
  border-radius: 6px;
  transition: all .3s linear;
  cursor: pointer;
}

.names div:hover {
  background-color: rgb(35, 172, 172);
}
<div class="app">
  <div class="names">
    <div class="yassir">Yassir</div>
    <div class="imane">Imane</div>
    <div class="khalil">khalil</div>
  </div>
  <div class="current-name">
    <div class="full-name">Name: Yassir Lasfar</div>
    <div class="active-age">Age : 17</div>
    <div class="favourite-song">Favourite song : way down we go</div>
  </div>
</div>

2

Answers


  1. There are multiple ways to achieve the desired result. I would suggest dynamically rendering the names on the left using JavaScript. Keeping your current implementation, I have done something like this:

    <div class="app">
      <div class="names">
        <div class="yassir" id="1">Yassir</div>
        <div class="imane" id="2">Imane</div>
        <div class="khalil" id="3">khalil</div>
      </div>
      <div class="current-name">
        <div class="full-name">Name: Yassir Lasfar</div>
        <div class="active-age">Age : 17</div>
        <div class="favourite-song">Favourite song : way down we go</div>
      </div>
    </div>
    

    Here, I added an ID to every clickable element that corresponds to the ID of the object that I added as a property on the infos array.

    const names = Array.from(document.querySelectorAll('.names div'));
    const activeName = document.querySelector('.current-name');
    
    const infos = [
      {
        id: '1',
        fullName: 'Yassir Lasfar',
        age: 17,
        favSong: 'Way Down We Go',
      },
      {
        id: '2',
        fullName: 'Imane Lasfar',
        age: 10,
        favSong: 'Mamamia',
      },
      {
        id: '3',
        fullName: 'Khalil Belajmia',
        age: 18,
        favSong: 'Half A Man',
      },
    ];
    
    for (let name of names) {
      console.log(name.id);
      name.addEventListener('click', () => {
        const info = infos.find((i) => i.id === name.id);
        if (info) {
          activeName.innerHTML = `
          <div class="full-name">Name: ${info.fullName}</div>
              <div class="active-age">Age : ${info.age}</div>
              <div class="favourite-song">Favourite song : ${info.favSong}</div>
          `;
        }
      });
    }
    

    Then, on the event listener, you have to find the corresponding info using the ID of the name, which is the clickable element in HTML.
    I have done a stackblitz example that you can find it here

    Hope so it helps!

    Login or Signup to reply.
  2. Don’t use <div> for everything. If those things are clickable, just use <button> and style them however you want. With that said, also remember what you’re trying to do: you have a number of people that you want a button for, so generate your buttons based on that data:

    const names = document.querySelector('.names');
    const current = document.querySelector('.current-name');
    const userData = [
      {
        fullName: 'Yassir Lasfar',
        age: 17,
        favSong: 'Way Down We Go'
      },
      {
        fullName: 'Imane Lasfar',
        age: 10,
        favSong: 'Mamamia'
      },
      {
        fullName: 'Khalil Belajmia',
        age: 18,
        favSong: 'Half A Man'
      }
    ];
    
    function setContent(name, age, song) {
      current.querySelector(`.full-name span`).textContent = name;
      current.querySelector(`.active-age span`).textContent = age;
      current.querySelector(`.favourite-song span`).textContent = song;
    }
    
    buttons = userData.map(data => {
      const { fullName: name, age, favSong: song } = data;
      const button = document.createElement(`button`);
      button.textContent = name;
      names.append(button);
      // add the "what should happen on click":
      button.addEventListener(`click`, () => setContent(name, age, song));
      return button;
    });
    
    // and "preselect" the first user by clicking their button
    buttons[0].click();
    <main class="app">
      <section class="names">
        <!-- our JS is going to fill this with buttons -->
      </section>
      <section class="current-name">
        <div class="full-name">Name: <span>-</span></div>
        <div class="active-age">Age: <span>-</span></div>
        <div class="favourite-song">Favourite song: <span>-</span></div>
      </section>
    </main>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search