Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Daniel Grieve
6,432 PointsCan't create a new event listener on a newly created jQuery object. Must use existing event listener on parent element.
I tried selecting a newly created element which for JS resulted in null
and for jQuery did nothing at all. I could, however, select it through its parent element. Is this the way its supposed to be?
My code is as follows
//contact class
document.addEventListener('DOMContentLoaded', () => {
//create a class to create contacts
class Contact {
constructor(first_name, middle_name, last_name) {
this.first_name = first_name
this.middle_name = middle_name
this.last_name = last_name
}
}
// //
//Event Listeners//
// //
$('.create').on('click', function (event) {
event.preventDefault()
if (event.target.textContent === 'Create contact') {
createForm('.create')
}
if (event.target.textContent=== 'Submit'){
alert('hello')
}
})
//MY TWO ATTEMPTS TO CREATE EVENT LISTENERS ON THE NEWLY CREATED ELEMENTS//
/*
const button = document.querySelector('button')
button.addEventListener('click', function () {
alert('hello')
})
$('button').on('click',function(){
alert('hello')
})
*/
//When the window loads, check if address book is empty.
$(window).on('load', function () {
if ($('.contact_list').find('li').length === 0) {
$('.contact_list').append($('<p>There are no contacts listed</p>'))
}
})
//creates form to input contact data
function createForm(parentNode) {
const form = "<form id = 'contact_form'><label>First Name </label><input><button class='create' type='submit'>Submit</button></form>"
$(parentNode).append(form)
}
//uses data from form to create contact
function createContact() {
const first_name = $('input').val()
const contact = new Contact(first_name, '', '')
}
})
The relevant html
<div class='create'>
<h2>Create contact</h2>
</div>
<div class = 'contact_list'>
<h3>List of Contacts: </h3>
</div>
1 Answer

Steven Parker
242,296 PointsThe "MY TWO ATTEMPTS" code is commented out, but it is also outside of the event handler.
So right now, if the comments were removed it would run when the DOM content was loaded, which is before any button has been created to attach a handler to.
You would also probably not want to use that kind of selector, since as each new button is added, additional listeners would be added to the buttons previously created.
Daniel Grieve
6,432 PointsDaniel Grieve
6,432 PointsHey, so I commented those out just to show what I had tried to do. So I understand that the
button
object is created before it actually exists in the DOM, but when its actually called upon (via one of the 2 methods I commented out) should the program not look back at all the previously defined variables and find it? Thanks for your help.Steven Parker
242,296 PointsSteven Parker
242,296 PointsThey would if you move them into the handler, but then you have the problem of multiple listeners.
On the other hand, this would be a good opportunity for a delegated handler:
This way, even buttons created later will be handled.
Daniel Grieve
6,432 PointsDaniel Grieve
6,432 PointsSorry, when you said 'move them into the handler', does that not mean move them inside the event listener?
So basically my intention was to use jQuery to create a form with new elements which could eventually submit data to my functions and Classes?
I'm just still unclear why my 2 attempts at creating event listeners failed when the button variable is globally defined.
Steven Parker
242,296 PointsSteven Parker
242,296 PointsThe "handler" is the function you pass when you establish a listener. It's what runs when the event happens.
Your 2 attempts did not use a "button" variable, but they used selection methods (one with jQuery, one with "querySelector") to find the "button" element(s). The failure was due to the code running during the "DOMContentLoaded" event, which happened before the button(s) had been created. So at that moment there were no buttons to add listeners to.
My suggestion about using a delegated handler avoids the problem by setting up a listener that will respond to buttons that are created later.
Daniel Grieve
6,432 PointsDaniel Grieve
6,432 PointsOk, so it seems that to add functionality to objects created later in the program, the general rule is that you must attach a delegated handler (or event listeners with if statements) to existing parent nodes. Thanks again for helping clear this up.
Steven Parker
242,296 PointsSteven Parker
242,296 PointsIt's not a "must" but it is usually convenient and efficient. You could also create individual handlers at the same time as you add the new elements.