Question

By default I want any buttons with a class '.options' to perform the same actions which is to alert('Hello World'). IF you look below, you will see another button with an id name called 'append_another_content'. It's job is to append another <input type="button" class=".options" value="Option"> and make it perform the same action as the rest of '.options' buttons. But the button that has just been appended will not perform any action unless I call myFunction() AGAIN, now the problem is once I call myFunction() again once the new content has been appended, the previous buttons with a class '.options' will call myFunction() repeatedly depending on how many times you pressed the 'Append' button. My goal is, to only call the myFunction() once per each time '.options' button is clicked.

<html>
    <head></head>
    <body>
        <div id="wrap">
            <input type="button" class=".options" value="Option">
            <input type="button" class=".options" value="Option">
            <input type="button" class=".options" value="Option">
            <input type="button" class=".options" value="Option">
        </div>

        <input type="button" id="append_another_content" value="Append"/>
    </body>

    <script>
        function myFunction(){
            $('.options').click(function(){
               alert('Hello Friends!');
            });
        }

        //By default I want any buttons with a class '.options' to perform the same actions which is to alert('Hello World')
        myFunction();

        $('#append_another_content').click(function(){
            $.ajax({
                type: 'POST',
                url: 'ajax/get_another_button.php',
            }).done(function(data){
                $('#wrap').append(data);
                //The data will just return '<input type="button" class=".options" value="Option">'

                //The button that has just been appended will not perform any action unless I call myFunction()
                myFunction();
            });

        }); 


    </script>
</html>
Was it helpful?

Solution

That's because the new element has no bound handlers, only the existing ones (the ones on the DOM before you called myFunction). Calling myFunction again adds yet another handler, and so on.

Consider using delegation instead, where an existing ancestor holds the handler for the existing and future descendants. The nearer the ancestor, the better. That way, you call myFunction only once.

In this example, the ancestor #wrap holds the handlers for .options. This will take effect for all existing and future .options.

HTML:

<div id="wrap">
    <input type="button" class="options" value="Option">
    <input type="button" class="options" value="Option">
    <input type="button" class="options" value="Option">
    <input type="button" class="options" value="Option">
</div>
<input type="button" id="append_another_content" value="Append" />

JS:

$('#wrap').on('click', '.options', function () {
  alert('Hello Friends!');
});

$('#append_another_content').click(function () {
  $(this)
    .siblings('#wrap')
    .append('<input type="button" class="options" value="Option">');
});

OTHER TIPS

First, get rid of the . in your HTML class attribute. As it stands, $(".options") selects nothing because there is no element with class="options". It should be

<input type="button" class="options" value="Option" />

Next, either add the click handler to the button when you create it:

$(/*...*/).appendTo($(this).siblings("#wrap")).click(handler);

or use delegation:

$("#wrap").on("click", ".options", handler);

When you add the event handler to the newly created element, you also add another event handler to all the previous elements.

You can add the event handler to only the element that you created:

function myFunction(e){
    $(e).click(function(){
       alert('Hello Friends!');
    });
}

myFunction('.options');

$('#append_another_content').click(function(){
    var input = $('<input type="button" class=".options" value="Option">');
    $(this).siblings('#wrap').append(input);
    myFunction(input);
});

Edit:

With the data from the AJAX call you can do exactly the same:

var input = $(data);
$('#wrap').append(input);
myFunction(input);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top