Andreas Remdt
Andreas Remdt

Reputation: 653

JavaScript Event Listener runs twice

As reference, please see my example in JSFiddle below. Every time somebody clicks on the plus button, a new row should be inserted below. This works fine except the fact that the amount of new rows inserted is always twice the amount of current existing rows. How can I avoid this strange behavior, or what's the reason for it? Please click the first rows button to see the issue.

http://jsfiddle.net/jrxeua6L/

var answers = [{
    order: 1,
    content: "placeholder"
}],
    appendAnswer = function() {

    answers.push({
        order: answers.length + 1,
        content: $(this).parent().prev().val()
    });

    $("#answers").empty();

    $.each(answers, function(key, value) {
        $("#answers").append('<div class="input-group"><input type="text" class="form-control" placeholder="Enter your answer"><span class="input-group-btn"><button type="button" class="btn btn-default" title="Add a question" data-action="add"><span class="glyphicon glyphicon-plus"></span></button><button type="button" class="btn btn-default" title="Delete this question" data-action="delete" disabled><span class="glyphicon glyphicon-trash"></span></button></span></div>');

        $("#answers button[data-action='add']").one("click", appendAnswer);
    });
};

$("#answers button[data-action='add']").one("click", appendAnswer);

Upvotes: 0

Views: 396

Answers (3)

Bojan Petkovski
Bojan Petkovski

Reputation: 6933

Here is a working solution http://jsfiddle.net/jrxeua6L/4/

var answers = [{
            order: 1,
            content: "placeholder"
        }],
            appendAnswer = function() {

            answers.push({
                order: answers.length + 1,
                content: $(this).parent().prev().val()
            });

            $("#answers").empty();

            $.each(answers, function(key, value) {
                $("#answers").append('<div class="input-group"><input type="text" class="form-control" placeholder="Enter your answer"><span class="input-group-btn"><button type="button" class="btn btn-default" title="Add a question" data-action="add"><span class="glyphicon glyphicon-plus"></span></button><button type="button" class="btn btn-default" title="Delete this question" data-action="delete" disabled><span class="glyphicon glyphicon-trash"></span></button></span></div>');

                //$("#answers button[data-action='add']").on("click", appendAnswer);
            });
        };

        $('body').on("click", "#answers button[data-action='add']", appendAnswer);

Upvotes: 0

Anton
Anton

Reputation: 32581

Use event-delegation

$("#answers").on("click", "button[data-action='add']",appendAnswer);

The cause of your problem is that you are binding multiple events on same elements in the each loop, so remove the delegation there.

Remove this line below from the .each() loop

$("#answers button[data-action='add']").one("click", appendAnswer);

DEMO

Upvotes: 2

Antony Jones
Antony Jones

Reputation: 581

Change this line:

$("#answers button[data-action='add']").one("click", appendAnswer);

To this:

$("#answers button[data-action='add']").off("click").one("click", appendAnswer);

Upvotes: -1

Related Questions