web-dev-qa-db-ja.com

jQueryを使用してダイアログを閉じるにはどうすればよいですか?

以下のコードを使用して、jQuery UI Dialogウィジェットを動的に作成しています。

 $(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;
        });
    });

最初に読み込まれたとき、jQueryダイアログは正しく機能し、btnCloseDialogをクリックすると、jQueryダイアログが正常に閉じます。

ただし、その後、btnCloseDialogはダイアログを閉じません。なぜこうなった?

更新

jsfiddle にコードを配置します。

ボタンはjsFiddleではダイアログを適切に閉じますが、プロジェクトのダイアログでは閉じないため、これは奇妙な動作です。

23
Shahin

これは、jqueryで動的ダイアログを作成するための検索の早い段階で表示されるため、これを行うためのより良い方法を指摘したいと思います。ダイアログdivとコンテンツをHTMLに追加して呼び出す代わりに、次のようにHTMLをjqueryオブジェクトに直接指定することで、これをはるかに簡単に行うことができます。

$(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;
    });
});

また、ボタンにlive()関数をアタッチする代わりに、インライン関数を使用して複数のボタンを配置する方法も示しました。私はこの方法をいくつかの場所で使用しましたが、私にとってはうまくいきます。また、フォームもサポートしています(私はdoSomething()でデータを取得し、ajax経由で送信しましたが、他のメソッドも機能します)など。

42

動的に作成されたコンテンツにIDを使用しないでください。同じIDを持つ複数の要素になる可能性があるため、document.getElementById(私はsizzleが#idセレクター)は、最初の(表示されない可能性がある)ものだけを返します。

3
kͩeͣmͮpͥ ͩ

クライアントがアクションを開始せずに、JSON Webサービスを使用してクライアント側でアラートや更新などを制御する方法が必要でした。 Webソケットを使用するようにこれを更新したいと思っていますが、今のところ、それは時限プルであり、各プルには次のプルの遅延が含まれているため、クライアントがシステムをロードすると、それを管理することもできます。

また、show/expireとmoment.jsを使用して日時でフィルタリングし、通知の重複を防ぐために各アラートのID(ここには表示されていません)を含むCookieを使用しています。これは順調に進んでおり、十分な関心が集まったら、いつの間にかライブラリとしてパッケージ化することを決定するかもしれません。

ただし、この質問に固有のビットは2つの部分です。 1)jQuery.dialog()のパラメーターを含むJSONおよび2)そのJSONを使用してダイアログを作成するコード。ここで重要なのは、「n」オブジェクトパラメータをどのように参照し、それらを使用してダイアログを動的に作成するかに注意を払うことです。 tDlgオブジェクトは、最終的にダイアログを表し、$()。dialog()に渡されるため、その大部分を占めています。

私のダイアログパラメータを含むJSONスニペット:

"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');"
                    }
                ]
            }

JSONに基づいてダイアログを初期化するJavaScriptスニペット(jQueryを使用)(nは、このサンプルでは「通知」の配列の一部であるdoAlertに対応しています):

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);
2
rainabba

個人的に、私はこのように管理しました:

1)ダイアログのhtmlを構築し、xxxをデフォルト値として2つのスパンを設定します

<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)divをダイアログとして準備する

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

3)ダイアログを起動する前に、この関数で2つのスパンの値を変更します。

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

4)必要に応じて、この方法で関数を呼び出します

showDialog('tom','jerry'); 

http://jsfiddle.net/sekmo/L46vb/1/ でこれを試すことができます

1
sekmo

考慮すべきいくつかのポイント:

  1. OnDialogClose同じIDを持つ複数のオブジェクトを避けるために、DOMから_#MenuDialog_を切り離す必要があります。または、オブジェクトを追加する前に_div#MenuDialog_が存在するかどうかを確認できます。

  2. var Selector = $("a:contains('sometext')");は、他の場所で再利用しない限り、意味のない行です。

  3. $('#MenuDialog')を複数回使用している。もう一度var Selector = $('#MenuDialog');をクエリするのではなく、変数に割り当てる方が良いでしょう。

1
eugeneK