I am adding the data received as a result of a request to my page as follows.
showMovieInfo(movies) {
this.tableDiv.innerHTML = "";
movies.forEach(movie => {
this.tableDiv.innerHTML +=
`
<table class="table align-middle mb-0 bg-white">
<thead class="bg-light">
<tr>
<th>Movie Name</th>
<th>Position</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center">
<img src="${movie.image}"
alt="" style="width: 120px; height: 120px" class="rounded-circle" />
<div class="ms-3">
<p class="fw-bold mb-1">${movie.title}</p>
<p class="text-muted mb-0">${movie.description}</p>
</div>
</div>
</td>
<td>
<button type="button" id="showonmap" class="btn btn-link btn-sm btn-rounded">
Show on map
</button>
</td>
</tr>
</tbody>
</table>`
});
}
then i want to add addEventListener to buttons with id="showonmap".But I am getting an error and when I click the buttons, any function does not work.
To support the comment made above regarding the delegated event listener I quickly rattled up this simple demo that slightly rewrites your original class method as a standalone function so that you can see the effect in action. As the event handler is assigned to a parent element within the DOM which does exist when the page is loaded you can use the event to identify which button ( or other element ) was clicked and from there do whatever operations are required.
const movies = [{
image: 'http://t1.gstatic.com/images?q=tbn:ANd9GcQsJW_I8KPZiq4mXcpRCd8uKBsUMR4Gz691k6gwEiLqVOoTl8pf',
title: 'The Life of Brian',
description: 'this is a great movie'
},
{
image: 'https://m.media-amazon.com/images/M/MV5BOTI4MDdjMmUtOTZhOS00MTYwLWEyZTUtYTdhMTQxNGM1YTUxXkEyXkFqcGdeQXVyMzg1ODEwNQ@@._V1_UX140_CR0,0,140,209_AL_.jpg',
title: 'The Wasp Woman',
description: 'this is a terrible movie'
}
];
// slightly re-written as no longer part of a class/object
showMovieInfo = (movies) => {
// exlicitly define this.tableDiv here rather than in constructor earlier ( & not shown )
this.tableDiv = document.getElementById('movies');
this.tableDiv.innerHTML = "";
movies.forEach(movie => {
this.tableDiv.innerHTML +=
`
<table class="table align-middle mb-0 bg-white">
<thead class="bg-light">
<tr>
<th>Movie Name</th>
<th>Position</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center">
<img src="${movie.image}"
alt="" style="width: 120px; height: 120px" class="rounded-circle" />
<div class="ms-3">
<p class="fw-bold mb-1">${movie.title}</p>
<p class="text-muted mb-0">${movie.description}</p>
</div>
</div>
</td>
<td><!-- modified id to data-id and added data-title for demo -->
<button type="button" data-id="showonmap" data-title="${movie.title}" class="btn btn-link btn-sm btn-rounded">
Show on map
</button>
</td>
</tr>
</tbody>
</table>`;
});
this.tableDiv.addEventListener('click', function(e) {
if (e.target != e.currentTarget && e.target.tagName == 'BUTTON' && e.target.hasAttribute('data-id')) {
alert(e.target.dataset.title);
// ... here you would do other operations to actually "view on map"
// ... etc
}
})
}
showMovieInfo(movies);
<div id='movies'></div>