append li to ul in jquery - onClick stopped working for newly added item

I'm facing an issue where i add a new LI to a UL and i'm unable to click it
Based on what i've read its to do with delegates and event handlers

<ul id="SchemeList" class="list-group">

   <li id="71" class="list-group-item">
      <a href="#">namegoeshere</a>
   </li>
</ul>

Open in new window



Here is the click event for the LI
   $('#SchemeList li').on('click', function () {
                alert(this.innerText); 
//...

Open in new window



Here is how i add the LI

<button class="btn btn-success" id="saveNewScheme" type="button" style="">Save New Scheme</button>

Open in new window


  $('#saveNewScheme').on('click', function () {

   var newSchemeId = 11;
   $("#SchemeList").append('<li class="list-group-item" id="' + newSchemeId + '"><a href="#">' + $("#schemeName").val() + '</a></li>');

Open in new window


should this work? or am i doing anything wrong (aside from using numbers for Id's
websssCEOAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
This is a classic problem with JavaScript event handling.

Let's look at what you are doing.
$('#SchemeList li').on('click', function () {
                alert(this.innerText);

Open in new window

This code is going to run at page load and it is going to find all li's in the SchemeList and bind a click event handler to them.

Now you add a new li. How is the browser expected to know it must bind a click handler to this element - it was not there when the code above ran - so nothing is going to be bound to it.

I think where the confusion comes in is from a misconception that somehow the $(...).on() is persistent - it is a rule that is always present. The truth is it is not - it runs once and then dies.

So how do we solve the problem of dynamic binding?

You are correct in your use of the .on() function - but incorrect in how you used it.

To bind to dynamic elements we need to bind to a static parent element and then tell jQuery to look for a specific event target when the event fires. How do we do this? By just doing a little rearranging of what you had before
$('#SchemeList').on('click', 'li', function () {
                alert(this.innerText); 
//...

Open in new window

What has changed? We have moved the li from the main selector to the second parameter of the .on(). If you have a look at the api docs for .on() you will see this
.on( events [, selector ] [, data ], handler )

Open in new window

Look at the second parameter - a selector.
What the code above does is it binds to the parent "#SchemeList" - when the click fires jQuery checks to see if the event target is an <li> element - if so the handler fires.

Now you can add as many <li> elements dynamically to your list and they will be "bound" to the event handler.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
websssCEOAuthor Commented:
Excellent explanation thanks, works great
Julian HansenCommented:
You are welcome.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.