How do I close a dialog using jQuery?
Asked Answered
R

5

23

I am using the code below to create a jQuery UI Dialog widget dynamically:

 $(function () {
        var Selector = $("a:contains('sometext')");
        $(Selector).bind('click', function () {
            var NewDialog = "<div dir=rtl id='MenuDialog'></div>";
            var DialogContetn = '<div dir=rtl ><table width=100%><tr><td><textarea id="txtRequestContent" cols="30" rows="2"></textarea></td><td><table><tr><td><input id="btnSendEditionRequest" type="button" value="Send" /></td></tr><tr><td><input id="btnCloseDialog" type="button" value="Cancel" /></td></tr></table></td></tr></table></div>';
            $('body').append(NewDialog);
            $('#MenuDialog').html(DialogContetn);
            $('#MenuDialog').hide();
            $('#MenuDialog').dialog({ modal: true, title: "title", show: 'clip', hide: 'clip' });
            $("#btnCloseDialog").live('click', function () {
                $("#MenuDialog").dialog('close');
            });
            return false;
        });
    });

First time it loads, the jQuery Dialog works correctly and when I click on the btnCloseDialog the jQuery Dialog closes successfully.

However, after that, the btnCloseDialog no longer closes the dialog. Why is this happening?

Update

I put my code out on a jsfiddle.

This is strange behavior because the button closes the dialog properly in the jsFiddle, but not on the dialog in my project.

Rubstone answered 15/6, 2011 at 7:30 Comment(4)
Just out of curiosity, why are yo using selector.bind instead of selector.click?Harville
Good question. Only on the habit. and does it affect performance ?Rubstone
I don't know for sure but i guess bind loops though collection of events for item you provided and then apply same function as click does. So i bet it does affect performance but this is how i would write this module. John Resig and others in jQuery crew might have much better ideas.Harville
@eageneK I checked : $('#test').click(function() { //whatever... }); is alias for below code. $('#test').bind('click', function() { //whatever... });Rubstone
J
42

Because this shows up early in the search for creating a dynamic dialog in jquery, I'd like to point out a better method to do this. Instead of adding your dialog div and content to the HTML and then calling it, you can do this much more easily by shoving the HTML directly into a jquery object, as so:

$(function () {
    $("a:contains('sometext')").click(function() {
        var NewDialog = $('<div id="MenuDialog">\
            <p>This is your dialog content, which can be multiline and dynamic.</p>\
        </div>');
        NewDialog.dialog({
            modal: true,
            title: "title",
            show: 'clip',
            hide: 'clip',
            buttons: [
                {text: "Submit", click: function() {doSomething()}},
                {text: "Cancel", click: function() {$(this).dialog("close")}}
            ]
        });
        return false;
    });
});

I've also showed how you can put multiple buttons with inline functions, instead of attaching a live() function to the button. I've used this method in a couple of places and it works great for me. It also supports forms (I grabbed the data in doSomething() and submitted through ajax, but other methods work too), etc.

Jorgan answered 25/10, 2011 at 16:13 Comment(1)
I tried using this code mostly as-is and FireBug is showing dialogs stacking at the end of the body tag in the DOM (once for each time I click to open the dialog). I think for this type of dynamic dialog you might want to use destroy instead of close -- $(this).dialog("destroy")Marlanamarlane
S
3

You should probably not use ids for dynamically created content, as you could end up with more than one element with the same id - meaning that document.getElementById (which I assume sizzle uses for the #id selector) will only return the first (potentially non-visible) one.

Stlouis answered 15/6, 2011 at 7:41 Comment(1)
How about this : if (Selector.lenght) { //Create Content dynamic }Rubstone
H
2

I needed a way to use a JSON webservice to control things like alerts and updates on the client-side without the client initiating an action. I hope to update this to use web-sockets, but for now it's a timed pull and each pull includes the delay for the next pull so I can even manage that once the client has loaded up my system.

I'm also using show/expire and moment.js to filter by datetime and then using cookies with the id of each alert (not shown here) to prevent duplicate notices. This is coming along nicely and I might just decide to package it up as a library before too long if I get enough interest.

The bit specific to this question is 2 parts though; 1) JSON that includes the parameters for the jQuery.dialog() and 2) The code to use that JSON and create a dialog. The key here is to pay attention to how I'm referencing the 'n' object parameters and using them to create the dialog dynamically. The tDlg object is a big part of that as it is what ultimately represents the dialog and is passed into $().dialog()

JSON Snippet that includes my dialog parameters:

"doAlert":{
                "modal":false
                ,"height":240
                ,"width":380
                ,"title":"Welcome to the new BatchManager"
                ,"body":"<div style='text-align:center;'>Welcome to the new and enhanced<br/>BatchManager!</div><div style='text-align:center;'>Enjoy!</div>"
                ,"buttons":[
                    {
                        "text":"Ok"
                        ,"click":"$(this).dialog('close');"
                    }
                ]
            }

JavaScript snippet (using jQuery) to initialize a dialog based on my JSON (n corresponds with doAlert, which is part of an array of "notices" in this sample):

var tDlg = {
    resizable: false,
    height: (n.doAlert.height) ? n.doAlert.height : 240,
    width: (n.doAlert.width) ? n.doAlert.width : 240,
    modal: (n.doAlert.modal) ? n.doAlert.modal : true,
    dialogClass: "dlgFont"
};
if (n.doAlert.buttons) {
    tDlg.buttons = [];
    $.each(n.doAlert.buttons, function (i, n) {
            tDlg.buttons.push({
                            text: n.text,
                            click: new Function(n.click)
                    })
    })
}
$('<div class="dlgFont" title="' + n.doAlert.title + '"><p><span class="ui-icon ui-icon-circle-check" style="float: left; margin: 0 7px 50px 0;"></span>' + n.doAlert.body + '</div>').dialog(tDlg);
Hypsometry answered 6/6, 2013 at 11:3 Comment(0)
H
1

A few points to think about:

  1. OnDialogClose you should detach #MenuDialog from DOM to avoid multiple objects with same ID or you can check whether div#MenuDialog exists before adding one.

  2. var Selector = $("a:contains('sometext')"); is a pointless line unless you re-use it else where.

  3. You use $('#MenuDialog') multiple times. It would be better to assign it to a variable instead of querying var Selector = $('#MenuDialog'); all over again .

Harville answered 15/6, 2011 at 7:49 Comment(0)
K
1

Personally, I managed in this way:

1) Build the html of the dialog, with two span with xxx as default value

<div id="dialog1" title="Title of the dialog">
    <p>There are two variables: <span id="var1">xxx</span> and
    <span id="var2">xxx</span></p>
</div>

2) Make the div ready for being a dialog

$(function() {
    $( "#dialog1").dialog({
    autoOpen:false,
        modal: true,
        buttons: {
        "Button 1": function() {
            $(this).dialog( "close" );
        },
        "Button 2": function() {
            $(this).dialog( "close" );
        }
    }
    });
});

3) And modifying the value of the two spans with this function, before firing up the dialog:

function showDialog(value1,value2){
    $("#var1").html(value1);
    $("#var2").html(value2);
    $( "#dialog1").dialog('open');
} 

4) So when you need it, call the function in this way

showDialog('tom','jerry'); 

You can try this at http://jsfiddle.net/sekmo/L46vb/1/

Kavanaugh answered 8/1, 2013 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.