Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery click action only fires once, per page refresh

Tags:

jquery

I have written a jQuery code in the admin section of my site that turns the site offline without page refresh. It works great, but for one thing:

When I click on TURN ON the ajax call is made accurately and all the classes are changed and the text is changed the TURN OFF. However, when I click on this text, nothing happens. If I reload the page, then I will be able to.

$("#switch_off").click(function() {
                $("#switch_off").html("<img style=\"padding-left:15px;\" src=\"/img/admin/ajax-loader.gif\">");
                $('#switch_off').removeClass('ttip_b')
                $.ajax({
                    url: "/settings/SwitchOffline",
                    type: "get",
                    data: '',
                    success: function(responseText, statusText, xhr, $form){ // Trigger when request was successful
                        $("#site_status").html("<span id=\"offline\" class=\"lbl error_bg\">Offline</span><span id=\"switch_on\" class=\"ttip_b\" title=\"Click to place Site Online\">Turn On</span>");
                    },
                    error: function(responseText){
                        //alert(responseText);
                    }   
                });
                return false;
            });

            $("#switch_on").click(function() {
                $("#switch_on").html("<img style=\"padding-left:15px;\" src=\"/img/admin/ajax-loader.gif\">");
                $('#switch_on').removeClass('ttip_b')
                $.ajax({
                    url: "/settings/SwitchOnline",
                    type: "get",
                    data: '',
                    success: function(responseText, statusText, xhr, $form){                            
                        $("#site_status").html("<span id=\"online\" class=\"lbl ok_bg\">Online</span><span id=\"switch_off\" class=\"ttip_b\" title=\"Click to place Site Offline\">Turn Off</span>");                          
                    },
                    error: function(responseText){
                        //alert(responseText);
                    }   
                });

                return false;
            });

ONLINEOFFLINE

HTML CODE WITH SOME PHP

<div class="user_info user_sep" style="width:90px;">
                            <p class="sepH_a">
                                <strong>Site Status</strong>
                            </p>
                            <?php
                            //debug($site_offline);
                            if($site_offline){
                            ?>                              
                            <span id="site_status">
                                <span id="offline" class="lbl error_bg">Offline</span>
                                <span id="switch_on" class="ttip_b" title="Click to place Site Online">Turn On</span>

                            </span>
                            <?php }else{ ?>
                            <span id="site_status">
                                <span id="online" class="lbl ok_bg">Online</span>
                                <span id="switch_off" class="ttip_b" title="Click to place Site Offline">Turn Off</span>

                            </span>
                            <?php } ?>
                        </div>
like image 963
AKKAweb Avatar asked Jan 06 '13 20:01

AKKAweb


2 Answers

Try using event delegation instead because you are rewriting the HTML on every click and the bindings are being lost. By making use of event delegation you are binding the event for present elements in the DOM and future ones that will be appended to the DOM such as those ones resulting from your AJAX calls.

Use

$("#site_status").on("click", "#switch_off", function() {
  ...
});

$("#site_status").on("click", "#switch_on", function() {
  ...
});

instead of

$("#switch_off").click(function() {
  ...
});

$("#switch_on").click(function() {
  ...
});

If #site_status is also being overwritten then use document.

like image 87
Alexander Avatar answered Nov 06 '22 14:11

Alexander


To expand on @Alexander's answer, the problem is that you're dynamically generating HTML content, but adding listeners on document initialization. This means that some of the elements you're attempting to bind to don't exist yet at the time of binding. Thus the listeners are never created. The solution is to use jQuery .on to "listen" for events on elements that don't exist yet:

$("#switch_off").click(function() {

Should be:

$(document).on('click', '#switch_off', function() {

And similarly:

$("#switch_on").click(function() {

Should be:

$(document).on('click', '#switch_on', function() {

However, as others have expressed, a better solution would be to clean up the code a bit and show/hide the respective states vs generating them on the fly.

like image 31
N Rohler Avatar answered Nov 06 '22 14:11

N Rohler