Search code examples
javascriptjqueryevent-bubbling

JQuery event doubling each time


$('.add_instruction_btn').click(function(e){
                    e.preventDefault();
                    var ins_content=$('#add_instructions').val();
                    var id=$('.useri').val();
                    if(ins_content!="")
                    {
                        //write new instructions to database
                        var id=$('.useri').val();
                        var data="job_id="+job_idx+"&ins="+ins_content+"&client_id="+id+"&key=2";
                        $.ajax({
                            type:"POST",
                            url:"admin_includes/get_instructions.php",
                            data:data,
                            success:function(html2){
                                alert(html2);
                            }
                        });//end ajax

                    }
                    return false;
                });

I seem to have tried evrything to stop the event from doubling each time the button is clicked. The code was originally inside another function which opened up a 'pop-up' style box but even when I move it outside the function it still seems to bubble.

As requested:-

$(document).on('click', '.bottom_links .lister a', function(e){
        //e.preventDefault();
        //e.stopPropagation();
        $('.ind_ins').text("");
        var ident=$(this).data('ref1');
        if(ident==1){
            var job_idx=$(this).data('job_id');
            var cl_name=$(this).data('cl_name');
            var icon_stat=$(this).data('img_id');
            var id=$('.useri').val();
            if(icon_stat=="1")
            {
                $('.opaque_scr,.instruction_popup').css('visibility', 'visible');
                $('.instruction_popup h2').html("Add Instructions for Appointment ID: "+job_idx);
                $('.client_name').html("<strong>Client Name: </strong>"+cl_name);
                //get original instructions
                var get_job="job_id="+job_idx+"&key=1";
                $.ajax({
                    type:"POST",
                    url:"admin_includes/get_instructions.php",
                    data:get_job,
                    success:function(html){
                        var split_data=html.split("^");
                        var split_data_count=split_data.length-1;
                        var ins_tb="<table width='100%'>"
                        for(var xs=0;xs<split_data_count;xs++)
                        {

                            var ind=split_data[xs].split("|");
                            var ind_count=ind.length-1;
                            for(var xx=0;xx<ind_count;xx++)
                            {
                                ins_tb+="<tr><td width='75%'>"+ind[0]+"</td><td>"+ind[1]+"</td></tr>";
                            }

                        }
                        ins_tb+="</table>";

                        $(ins_tb).appendTo('.ind_ins');
                    }

                })//end ajax

                $('.add_instruction_btn').click(function(e){
                    e.preventDefault();
                    e.stopPropagation();
                    var ins_content=$('#add_instructions').val();
                    var id=$('.useri').val();
                    if(ins_content!="")
                    {
                        //write new instructions to database
                        var id=$('.useri').val();
                        var data="job_id="+job_idx+"&ins="+ins_content+"&client_id="+id+"&key=2";
                        $.ajax({
                            type:"POST",
                            url:"admin_includes/get_instructions.php",
                            data:data,
                            success:function(html2){
                                alert(html2);
                            }
                        });//end ajax

                    }
                    return false;
                });


            }

        }

Solution

  • The problem is that you're hooking up the event handler more than once. Each time an element matching '.bottom_links .lister a' is clicked, provided various conditions are right, you re-run this code:

    $('.add_instruction_btn').click(function(e){
        // ....
    });
    

    Each time you run that code, you hook up a new copy of the handler.

    If the set of elements matching '.add_instruction_btn' is fixed, just move that code out of the click handler for '.bottom_links .lister a' elements.

    If the set of elements matching '.add_instruction_btn' varies, you still want to move the code outside the click handler for '.bottom_links .lister a' elements, but you probably want to make it use event delegation, too, as you do with the '.bottom_links .lister a' one.

    A note about event delegation: You're "rooting" your event delegation on document, which is really, really high up. It's best to root delegation in the nearest container you can to the elements you're watching for. Obviously, if document is the nearest container, well, there you are, but there's usually something a bit further down you can use instead, while still getting the benefits of delegation.