1

Im trying to develop a chat app that allows for users to create a new chat room.

I already have code that runs for each item in the list, on click, will add users to the new room

Javascript:

document.querySelectorAll('.select-room').forEach(li => {
    li.onclick = () => {
        let newroom = li.innerHTML;
        if (newroom == room){
            msg = `You are already in ${room} room.`
            printSysMsg(msg);
        } else {
            leaveRoom(room);
            joinRoom(newroom);
            room = newroom;
        }
    }
});

HTML:

            <nav id='sidebar'>
            <h4>ROOMS</h4>
            <ul id='room_list' >
                {% for room in rooms %}
                    <li class = 'select-room'>{{ room }}</li>
                {% endfor %}
            </ul>                
        </nav>

However, when i add new rooms, im not able to click on the list item straight away to change chat rooms, i would have to refresh the page.

Any help would be greatly appreciated

  • You can find a solution from below post; https://stackoverflow.com/questions/16598213/how-to-bind-events-on-ajax-loaded-content – UgurVolkan Nov 30 '19 at 15:36
  • @UgurVolkan I don't think that your link will help as the solutions there are written in jQuery and not in vanilla JS. jQuery has a completely different syntax and uses Event Delegation for problems like this. – Aaron3219 Nov 30 '19 at 16:03

2 Answers2

1

Have you tried adding an event listener? So in your forEach:

document.querySelectorAll('.select-room').forEach(li => {
    li.addEventListener('click', () => {
        let newroom = li.innerHTML;
        if (newroom == room){
            msg = `You are already in ${room} room.`
            printSysMsg(msg);
        } else {
            leaveRoom(room);
            joinRoom(newroom);
            room = newroom;
        }
    })
});
JakeCroth
  • 19
  • 2
1

You have to add the event listener again to each element you add. But not like JakeCroth tried to explain (at least if I understand you correctly). Instead, try it like this:

let lst = document.querySelector('.lst');
let btn = document.querySelector('.btn');

function addListItem() {
  let li = document.createElement('li');
  
  li.innerHTML = "New element";  
  li.addEventListener('click', testTheEventListener);
  lst.appendChild(li);
}

function testTheEventListener() {
  console.log("The event listener works!");
}

document.querySelectorAll('li').forEach(li => {
  li.addEventListener('click', () => {
    testTheEventListener();
  });
});
<ul class='lst'>
  <li class="listItem">First</li>
  <li class="listItem">Second</li>
  <li class="listItem">Third</li>
</ul>

<button onclick="addListItem()" class='btn'>Add item</button>

So as you can see I add the event listener to all existing items:

document.querySelectorAll('li').forEach(li => {
  li.addEventListener('click', () => {
    testTheEventListener();
  });
});

And if an item gets added dynamically I add the event listener to this item as well.

function addListItem() {
  let li = document.createElement('li');

  li.innerHTML = "New element";  
  li.addEventListener('click', testTheEventListener); //<--
  lst.appendChild(li);
}

If I understood you wrong, just feel free to correct me.

Aaron3219
  • 2,168
  • 4
  • 11
  • 28
  • Do you understand it? Did I understand you correctly? – Aaron3219 Nov 30 '19 at 16:50
  • Yup you have understood me right. i needed to add the event listener to each of the dynamically added items in order for them to gain that functionality. Just that adding those lines of code seems to break it. The links are no longer added. I think i just have to troubleshoot this issue –  Nov 30 '19 at 17:29
  • Glad I could help. Don't forget to mark it as correct. – Aaron3219 Nov 30 '19 at 17:30