Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery - append() doesn't work a second time after using empty()

Tags:

jquery

I want to show a register / login form within a dialog (lightbox style), but both are only shown once when clicking on a trigger hyperlink. After clicking once, the page will still blur but the dialog won't show anything.

This code works fine when ommiting the empty() function, but then both the login and register form are shown in 1 dialog. When a user clicks on the login link I want to show only the login form, and when users click on the register hyperlink I want to show only the register form.

See the code below (HTML, CSS, jQuery).

    <html>
    <head>
    <style>

        #lightbox {
            position:fixed;
            top:0; 
            left:0; 
            width:100%; 
            height:100%; 
            background:rgba(0,0,0,0.5);
            display:none;
        }

        #invisible_register, #invisible_login {
            display:none;
            position:absolute;
        }

    </style>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script>
        jQuery(document).ready(function($) {

            $('.trigger_register').click(function(e) {
                e.preventDefault();
                $('#lightbox').empty().append($('#invisible_register'));
                $('#lightbox').show();
                $('#invisible_register').show();
            });

            $('.trigger_login').click(function(e) {
                e.preventDefault();
                $('#lightbox').empty().append($('#invisible_login'));
                $('#lightbox').show();
                $('#invisible_login').show();
            });

            //Click anywhere on the page to get rid of lightbox window
            $("#lightbox").click(function() {
                $('#lightbox').hide();
            });

            //Except for the dialog box
            $(".dialog").click(function(e) {
                e.stopPropagation();
                return false;
            });   
        });
    </script>
</head>
<body>

    <div id="lightbox"></div>

    <div id="invisible_register">
        <div class="container">
            <div class="dialog">
                <div class="box">
                    <div class="box_left">
                        <h1>Register</h1>
                    </div>
                    <div class="box_right">
                        <div class="error_text"></div>
                    </div>
                    <div class="clear"></div>
                </div>
            </div>
        </div>     
    </div>

    <div id="invisible_login">
        <div class="container">
            <div class="dialog">
                <div class="box">
                    <div class="box_left">
                        <h1>Login</h1>
                    </div>
                    <div class="box_right">
                        <div class="error_text"></div>
                    </div>
                    <div class="clear"></div>
                </div>
            </div>
        </div>     
    </div> 

    <a href="" class="button trigger_register">Register</a>
    <a href="" class="button trigger_login">Login</a>

</body>
</html>

Or see this fiddle for a quick example of the problem: http://jsfiddle.net/zwprf0yw/

edit The clone() functions works well, however this causes another problem: the dialog box gets closed when clicking on it. I think it prevents this block of code from working. Any suggestions?

        $(".dialog").click(function(e) {
            e.stopPropagation();
            return false;
        });
like image 421
guy1997 Avatar asked Feb 12 '23 22:02

guy1997


1 Answers

You have to .clone() the elements before appending them. If you don't, then your call to .empty() eliminates them forever.

Here is the fixed fiddle.

            $('.trigger_register').click(function(e) {
                e.preventDefault();
                $('#lightbox').empty().append($('#invisible_register').clone());
                $('#lightbox').show();
                $('#invisible_register').show();
            });

            $('.trigger_login').click(function(e) {
                e.preventDefault();
                $('#lightbox').empty().append($('#invisible_login').clone());
                $('#lightbox').show();
                $('#invisible_login').show();
            });

When you find an existing element and then .append() it somewhere else, it gets removed from its original home.

edit — In order to make this really work, event handling should be done via delegation:

            //Click anywhere on the page to get rid of lightbox window
            $(document).on("click", "#lightbox", function() {
                $('#lightbox').hide();
            });

            //Except for the dialog box
            $(document).on("click", ".dialog", function(e) {
                e.stopPropagation();
                return false;
            });   

That way, events for the cloned dialogs will be properly handled.

like image 83
Pointy Avatar answered Feb 14 '23 23:02

Pointy