2

I'm creating new input field with JQuery that include a remove button. The remove button works on the original element but does not work on those that were created using JQuery.

document after two new email fields added

<fieldset>
                <legend>Send Email</legend>
                <label>Emails(s) to send notice to.</label>
                <p>
                    <input type="email" name="emails[]" style="cursor: auto; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVQ4EaVTO26DQBD1ohQWaS2lg9JybZ+AK7hNwx2oIoVf4UPQ0Lj1FdKktevIpel8AKNUkDcWMxpgSaIEaTVv3sx7uztiTdu2s/98DywOw3Dued4Who/M2aIx5lZV1aEsy0+qiwHELyi+Ytl0PQ69SxAxkWIA4RMRTdNsKE59juMcuZd6xIAFeZ6fGCdJ8kY4y7KAuTRNGd7jyEBXsdOPE3a0QGPsniOnnYMO67LgSQN9T41F2QGrQRRFCwyzoIF2qyBuKKbcOgPXdVeY9rMWgNsjf9ccYesJhk3f5dYT1HX9gR0LLQR30TnjkUEcx2uIuS4RnI+aj6sJR0AM8AaumPaM/rRehyWhXqbFAA9kh3/8/NvHxAYGAsZ/il8IalkCLBfNVAAAAABJRU5ErkJggg==); background-attachment: scroll; background-position: 100% 50%; background-repeat: no-repeat;"><span class="btn_orange"><a href="#" class="remove_field">x</a></span>
                </p>
                <p><input type="email" name="emails[]"><span class="btn_orange"><a href="#" class="remove_field">x</a></span></p><p><input type="email" name="emails[]"><span class="btn_orange"><a href="#" class="remove_field">x</a></span></p><p>
                    <span class="btn_orange"><a class="add_email_button" href="#">Add Another Email</a></span>
                </p>
                <p>
                    <span class="btn_orange"><a class="ui-button">Send Email</a></span>
                </p>
            </fieldset>

Script

<script type="text/javascript">
    $(document).ready(
        function () {
            $("#importbutton").click(function () {
                $("#ProgressBarImg").show();
                $.get('@Url.Action("Import", "Import")', {},
                function (data) {
                    $('body').html(data);
                    $('#ProgressBarImg').hide();
                });
                $("#importbutton").removeAttr("href");
            }
            );

            var dialog = $("#emailSection").dialog({
                autoOpen: false,
                height: 400,
                width: 475,
                modal: true
            });

            $('#emailButton').click(function () {
                $(dialog).dialog("open");
                $('#emailButton').removeAttr('href');
            });
            $('.add_email_button').closest('p').click(function () {
                var html = '<p><input type="email" name="emails[]" /><span class="btn_orange"><a href="#" class="remove_field">x</a></span></p>';
                $(html).insertBefore($(this));
            });

            $('a.remove_field').closest('p').click(function () {
                $(this).remove();
            });
        }
    );
</script>
Antarr Byrd
  • 24,863
  • 33
  • 100
  • 188
  • 3
    Use `on` to attach events -- it uses event delegation. This used to be called `live`. So, `$('.mySelector').on('click', function () {});` – Chris Baker Sep 09 '14 at 21:01
  • @Chris What you have doesn't use event delegation, you have to use `$(document).on('event', delegateSelector)` However, in this case, there's no selector to get the `p` above the `a.remove_field`, so you couldn't really use that, unless you added a class to the p that the OP is adding the click handler to – Ruan Mendes Sep 09 '14 at 21:02
  • @JuanMendes All true. My comment was not thoroughly accurate; however, it was merely intended to point the OP in the right direction. Too late to edit now, but the dup question has an answer with detail, as do the docs – Chris Baker Sep 09 '14 at 21:11

2 Answers2

2

You're setting an event on the element that is on the page initially. After you add new elements, the new elements don't have the handler, you could add it ass you add them, but that's the best way.

Use event delegation: http://jsfiddle.net/mendesjuan/4my1dhw1/

$(document).on('click', 'a.remove_field', function () {
    $(this).closest('p').remove();
});

That means you are listening for clicks on the whole document, but filtering for only the ones you're interested in.

The second benefit is that you don't need a separate handler for each element, saving you memory

The code I posted differs in behavior from what you had in that it requires that you click the x. Your code would delete when you click anywhere in the <p>. The reason I changed it is because there is no CSS selector that mimics what closest('p')does, that is CSS selectors do not go up the tree. However, what I have seems to make more sense, and you probably were using closest('p') only because you wanted to delete the entire <p>, but you can do that from inside the handler.

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
0

For elements that were added after page load you should use:

 $('body').on('click', '.classSelector', function(e) {

});
Tim
  • 785
  • 1
  • 7
  • 20