Ramon Vasconcelos
Ramon Vasconcelos

Reputation: 945

Dynamic button not calling function

I'm trying to create a simple modal function using javascript.

html:

<button id="button">open</button>

js:

// define box width
            var boxHeight = 200,
                modal = $('<div id="modal" class="modal-fade"><button class="close">close x</button><div id="foo" /></div><div id="overlay" class="modal-fade" />');

            $('body').append(modal);

            // modal open function
            function openModal(boxHeight){ 
                $('#modal').css({
                    height: boxHeight,
                    marginTop: -(boxHeight / 2)
                });

                $('#modal, #overlay').fadeIn(200);
            }

            // modal close function , removes its elements and append it again
            function closeModal(){
                $('body').find('#modal, #overlay').fadeOut(200, function(){
                    $(this).remove();
                    $('body').append(modal);
                });
            }

            // modal open onclick
            $('#button').on('click', function(e){
                e.preventDefault();

                openModal(boxHeight);
            });

            // modal close onclik
            $('body').find('#modal button.close').on('click', function(e){
                e.preventDefault();

                closeModal();
            });

Everything works great at the first time. First, I click on button#button, that calls openModal(), it opens the modal and then when I click on .close, that calls closeModal() it closes the modal, removes it from DOM and then the modal's structure is appended to the body again via $('body').append(modal). The second time it breaks. The modal opens but closeModal() doesn't work when I click button.close.

JSFiddle: https://jsfiddle.net/gemrw44k/1/

Upvotes: 0

Views: 40

Answers (4)

Nitesh
Nitesh

Reputation: 1550

OK, what you are trying to do is:

You want to delete a DOM element and then append it again. But you want to handle event handling only once so that next time same element is available in DOM element, same event handling should work.

For that you need to use jQuery on with proper syntax and arguments as: https://jsfiddle.net/gemrw44k/4/

// modal close onclik
$('body').on('click','#modal button.close', function(e){
    e.preventDefault();

    closeModal.call($(this)[0]);
});

Notice, how I am using 2nd argument in on function. This binds event at body and execute only when event occurs on 2nd argument selector.

Also notice, since you want to remove close button, you should not directly call closeModal() because then this will be window. Use call function as mentioned above.

Upvotes: 0

sesamechicken
sesamechicken

Reputation: 1981

It's your event listener. Once you remove the modal from the dom, your event listener is done for.

This works, although very ugly.

$(function(){

        // define box width
        var boxHeight = 200,
            modal = $('<div id="modal" class="modal-fade"><button class="close">close x</button><div id="foo" /></div><div id="overlay" class="modal-fade" />');

        $('body').append(modal);

        // modal open function
        function openModal(boxHeight){ 
            $('#modal').css({
                height: boxHeight,
                marginTop: -(boxHeight / 2)
            });

            $('#modal, #overlay').fadeIn(200);
            // modal close onclik
        $('body').find('#modal button.close').on('click', function(e){
            e.preventDefault();

            closeModal();
        });
        }

        // modal close function , removes its elements and append it again
        function closeModal(){
            $('body').find('#modal, #overlay').fadeOut(200, function(){
               // $(this).remove();
                $('body').append(modal);
            });
        }

        // modal open onclick
        $('#button').on('click', function(e){
            e.preventDefault();

            openModal(boxHeight);
        });

        // modal close onclik
        $('body').find('#modal button.close').on('click', function(e){
            e.preventDefault();

            closeModal();
        });

    });

Upvotes: 0

BrTkCa
BrTkCa

Reputation: 4783

I don't know the reason to remove element from DOM, but you can to use delegate in close method:

// modal close onclik
$(document).on('click', '#modal button.close', function(e){
    e.preventDefault();                
    closeModal();
});

Fiddle

Upvotes: 1

Oligopoly
Oligopoly

Reputation: 1

Remove $(this).remove();

This line of code removes your modal from the DOM. Which you still need.

 // modal close function , removes its elements and append it again
            function closeModal(){
                $('body').find('#modal, #overlay').fadeOut(200, function(){
                    // $(this).remove();
                    $('body').append(modal);
                });
            }

Upvotes: 0

Related Questions