Joel Hines Joel Hines - 4 months ago 10
Javascript Question

How to reinitialize button that has been removed from the DOM?

So I'm running into an issue using a program called XCrud, that is supposed to help with database management. The gist of the issue is that the program removes and reinserts its buttons into the DOM, causing my click functions in JQuery to stop working.

$('a[class="btn btn-warning xcrud-action"]').on('click', function() {
intvId = window.setInterval(cleanup, 200);
});


This button is supposed to reset an interval that helps the user along the workflow of the database, but as aforementioned, the button will only trigger once.

Thanks for the help everyone

Answer

Use this syntax instead, to delegate the event handler to all members of the class, present and future:

$('parent').on('click', 'a.btn.btn-warning.xcrud-action', function() {
     intvId = window.setInterval(cleanup, 200);
});

Where parent is an element higher up in the DOM tree than the a element you're targeting. (I'm assuming with this selector that all the classes in your example apply to a single a element.) This syntax supersedes the older delegate method. As the doc states:

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.

Unfortunately, the doc also fails to spell out that the [selector] argument of the on method delegates the handler to members of the classes in the selector. You can find that out by looking at the older delegate doc, and examining the examples that they give to convert from delegate to on.

Here's a little working example:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>
        Test
    </title>

    <!--jQuery and jQuery-UI files-->
    <script src="includes/jquery/jquery-2.2.3.js"></script>    
    <script src="includes/jquery-ui/external/jquery/jquery.js"></script>

    <script type="text/javascript">
        $(document).ready(function () {
            $('form').on('click', 'button.test1.test2', function(e, ui){
                $('form').append('<button type="button" class="test1 test2">"Test"</button>')
                alert('click');
            });
        });
    </script>
</head>
<body>
<form>
    <button type="button" class="test1 test2">Test</button>
</form>
</body>
</html>

Any new button will have the same behavior as the original one.