Johnny Wales
Johnny Wales

Reputation: 487

JQuery onClick works only once

I have checked several answers to this question and I am not getting anything to work. I have a set of buttons that will trigger an Ajax call, and that call will replace the buttons with new ones with updated information. This works on the first click, but not on any subsequent clicks.

The button group looks like this:

<div class="btn-toolbar" role="toolbar" aria-label="Voting Toolbar">
    <div class="leanVote_target">
        <div class="btn-group mr-2" role="group" aria-label="Lean Votes">
            <button type="button" id="2_-3" {% if vote.leanVote == -3 %} class="voteButton btn-sm btn-success"{% else %} class="voteButton btn-sm btn-primary"{% endif %}>Left</button>
            <button type="button" id="2_-2" {% if vote.leanVote == -2 %} class="voteButton btn-sm btn-success"{% else %} class="voteButton btn-sm btn-primary"{% endif %}>2</button>
            <button type="button" id="2_-1" {% if vote.leanVote == -1 %} class="voteButton btn-sm btn-success"{% else %} class="voteButton btn-sm btn-primary"{% endif %}>1</button>
            <button type="button" id="2_0" {% if vote.leanVote == 0 %} class="voteButton btn-sm btn-success"{% else %} class="voteButton btn-sm btn-primary"{% endif %}>Center</button>
            <button type="button" id="2_1" {% if vote.leanVote == 1 %} class="voteButton btn-sm btn-success"{% else %} class="voteButton btn-sm btn-primary"{% endif %}>1</button>
            <button type="button" id="2_2" {% if vote.leanVote == 2 %} class="voteButton btn-sm btn-success"{% else %} class="voteButton btn-sm btn-primary"{% endif %}>2</button>
            <button type="button" id="2_3" {% if vote.leanVote == 3 %} class="voteButton btn-sm btn-success"{% else %} class="voteButton btn-sm btn-primary"{% endif %}>Right</button>
        </div>
    </div>
</div>

So it will be a primary if it is not the selected one, and a success button if it is the selected one. Then, I have the following JQuery code:

<script>
    function sendVote(id, type, vote) {
        $.ajax({
            url:'/webproxy/v/?i=c&pk=' + id + '&t='+type+'&v='+vote,
            type:'get',
            dataType:'html',
            crossDomain:true,
            success:function(data) {
                if(type == 2) {
                    $(".leanVote_target").html(data);
                } else if (type == 1) {
                    $(".credVote_target").html(data);
                } else if (type == 3) {
                    $(".controlVote_target").html(data);            
                }
            },
            error: function(data) {
                return data;
                //$(".leanVote_target").html(data);
            }
        });
    }

    $(document).ready(function(){
        $(".btn-group").on("click", '.voteButton', function( event ) {
            var parts = event.target.id.split("_");
            sendVote({{comment.id}}, parts[0], parts[1]);
        });
    });
</script>

This correctly sends the vote to /webproxy/v/ on the first click. The script at /webproxy/v/ then returns an identical btn-group, but with the updated color to show the most recent vote. I can confirm that works, the color updates, the database updates, and I can see the request in my web server logs. On the second click, the event doesn't fire. I have tried doing a console.log('hello world') inside the on-click event, and so I am sure it is at that level where I have the failure. The on-click event is not firing on the second click, so if I choose 1, then choose 2, I should see 2 requests to the server and 2 firings of on click events, but I am not.

Here is the return output from the /webproxy/v/ script after clicking on a 2:

<div class="btn-group mr-2" role="group" aria-label="Lean Votes">
    <button type="button" id="2_-3"  class="voteButton btn-sm btn-primary">Left</button>
    <button type="button" id="2_-2"  class="voteButton btn-sm btn-primary">2</button>
    <button type="button" id="2_-1"  class="voteButton btn-sm btn-primary">1</button>
    <button type="button" id="2_0"  class="voteButton btn-sm btn-primary">Center</button>
    <button type="button" id="2_1"  class="voteButton btn-sm btn-primary">1</button>
    <button type="button" id="2_2"  class="voteButton btn-sm btn-success">2</button>
    <button type="button" id="2_3"  class="voteButton btn-sm btn-primary">Right</button>
</div>

Why is this not registering the .on('click') and how do I get it to respond a limitless number of times?

Thank you.

Upvotes: 0

Views: 73

Answers (2)

ChekTek
ChekTek

Reputation: 174

if(type == 2) {
    $(".leanVote_target").html(data);
} else if (type == 1) {
    $(".credVote_target").html(data);
} else if (type == 3) {
    $(".controlVote_target").html(data);            
}

The conditional above is replacing the the btn-group using .html(), so the $(".btn-group") you placed the listener on is replaced with a new btn-group. you can fix your issue by placing the listener on an element that does not get replaced in the DOM.

$(".btn-toolbar").on("click", '.voteButton', function( event ) {

Upvotes: 1

Taplar
Taplar

Reputation: 24965

$(".btn-group").on("click", '.voteButton', function( event ) {

Your delegate binding is on the btn-group, but it looks like you are dynamically creating btn groups. Delegate bind higher on something that is not dynamically created.

Since you are appending the html to one of three elements, you could possibly delegate bind on them.

$(".leanVote_target, .credVote_target, .controlVote_target").on("click", '.btn-group .voteButton', function( event ) {

Upvotes: 2

Related Questions