On Click Event fires only once

Hi Experts,

I have the following code, which works when the documents first loads
$(document).ready(function(){
    
    //Display App't Setter
    $('#aApptSetter').on('click', function(){
       //$('#divNextAppt').css('display', 'none'); 
       $('#divApptSetter').css('display', 'block');
    });
});

Open in new window


However, after I fire the below, the above no longer reacts?
function updateAppt(data){
    
    var gmail_id = data.event_id;
    var appt = data.date + ' at ' + data.time;
    
    var html = "";
    html += "<label>The next appointment for this client is <b>" + appt; 
    html += "</b> Click <a id=\"aApptSetter\">here</a> to change.</label>";
    
    $('#divNextAppt').html(html);
    $('#gmail_id').val(gmail_id);
    
    $('#slots').children().remove();
    $('#weeks').children().remove();
    
    $('#divApptSetter').css('display', 'none');
}

Open in new window


When the document loads, the  original HTML is
<div id="divNextAppt">
                
                                    <label>No upcoming appointments for this client.
                            Click <a id="aApptSetter">here</a> to set.</label>
                    
            </div>

Open in new window


Any help will be appreciated.
APD TorontoAsked:
Who is Participating?
 
Chris StanyonConnect With a Mentor Commented:
In jQuery, you bind event handlers to elements, such as binding a Click event handler to a Button. Often, this will be Direct binding - you bind the Click event directly to a Button:

$('#someButton').on('click', function() { do something });

Doing this means that firstly, the element needs to already exist when you call that code, and secondly, if you delete that element, you delete the event handler along with it.

To avoid these issues, you can Delegate the event handler - effectively passing off the responsibility for the event to a different element that you know exists and won't be deleted:

$('#someOtherElement').on('click', '#someButton', function() { do something });

This stores the event binding on the #someOtherElement ready to fired by the #someButton element (if and when it exists). You can add and delete #someButton at any time without affecting the event because it's been delegated to #someOtherElement.

Now in your case, you currently use Direct binding to bind the click event to your #aApptSetter element. When you delete the element (by re-creating the HTML), you also delete the event with it, which is why it won't fire a second time.

By delegating the event to #divNextAppt, the event handler won't be deleted when you delete #aApptSetter and will continue to fire, no matter how many times you re-create the element.

:)
0
 
Chris StanyonCommented:
Your Click event is bound to the #aApptSetter when the page first loads, but then you replace the conteint of divNextAppt with new HTML, so you also replace the aApptSetter with a new copy. This new copy doesn't have the event bound to it.

What you need to do is delegate the event binding to the parent DIV (the one that doesn't get replaced):

$('#divNextAppt').on('click', '#aApptSetter',  function() {
...

Open in new window

0
 
Leonidas DosasCommented:
Encapsulate the event click also into the function scope ie
$(document).ready(function(){
    
    //Display App't Setter
    $('#aApptSetter').on('click', function(){
       //$('#divNextAppt').css('display', 'none'); 
       $('#divApptSetter').css('display', 'block');
    });


function updateAppt(data){
    
    var gmail_id = data.event_id;
    var appt = data.date + ' at ' + data.time;
    
    var html = "";
    html += "<label>The next appointment for this client is <b>" + appt; 
    html += "</b> Click <a id=\"aApptSetter\">here</a> to change.</label>";
    
    $('#divNextAppt').html(html);
    $('#gmail_id').val(gmail_id);
    
    $('#slots').children().remove();
    $('#weeks').children().remove();
    
    $('#divApptSetter').css('display', 'none');
  
     $('#aApptSetter').on('click', function(){
       //$('#divNextAppt').css('display', 'none'); 
      $('#divApptSetter').css('display', 'block');
    });
}

});

Open in new window

0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
APD TorontoAuthor Commented:
I’m currently out of my office, but I believe that I tried, same issue.
0
 
Chris StanyonCommented:
There's absolutely no need to repeat the event binding in the updateAppt() function. All that's needed is to delegate the event, as I've already shown.

You can see it working here -> https://jsfiddle.net/ChrisStanyon/6xzqyx3y/

If you say that doesn't work, then there's something else going on in your code that you're not showing us.
0
 
APD TorontoAuthor Commented:
Chris, I heard about delegation before.  What is it?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.