6

デフォルトの確認ダイアログを置き換えるために、jQuery UI(または他のダイアログプラグイン)を利用しようとしています。StackOverflowには、同様の質問と回答がたくさんあります。たとえば、次のようになります。

jqueryダイアログ:送信ボタンのクリックを確認します

それでも、ASP .NETでは、さらに何かが必要です。

ページ制約の1つのフォームにより、ASP .NETページ(ASP .NET 3.5で動作)に同じフォームを送信する複数のボタンを設定できます。送信されたヘッダー情報に基づいて、ページはどのコントロール(ボタン)がフォームの送信をトリガーしたかを認識します。サーバーで正しいメソッドを呼び出すことができます(ButtonのClickイベントにアタッチされたメソッド)。

たとえば、他のStackOverflowの回答のソリューションを使用する場合:

        buttons: {
            'Delete all items': function() {
                $(this).dialog('close');
                currentForm.submit();
            },
            'Cancel': function() {
                $(this).dialog('close');
            }
        }

PostBackではイベントハンドラーは呼び出されません。私がそれを置き換える場合:

        buttons: {
            'Delete all items': function() {
                $(this).dialog('close');
                $buttonThatWasConfirmed.click();
            },
            'Cancel': function() {
                $(this).dialog('close');
            }
        }

その結果、モーダルダイアログが無限に再帰します。ASP .NETでそれを解決する方法は?

4

6 に答える 6

3

オプションとして:SubmitBehavior="false"ボタンコントロールに使用し、フォームの終了タグの前にスクリプトを下に配置します。

<script type="text/javascript">
    var originalDoPostBack = __doPostBack;
    __doPostBack = function (sender, args) {
        $("#dialog").dialog({
            modal: true,
            title: "Confirm action",
            buttons: {
                Yes: function () {
                    $(this).dialog("close");
                    originalDoPostBack(sender, args);
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });
    };
</script>

特定のボタンに対してのみ明示的に通話確認が必要な場合は、以下のスクリプトを使用できます(ヘッダーに配置できます)。

function confirmPostBack(sender, args) {
    $("#dialog").dialog({
        modal: true,
        title: "Confirm action",
        buttons: {
            Yes: function () {
                $(this).dialog("close");
                __doPostBack(sender.name, args || "");
            },
            Cancel: function () {
                $(this).dialog("close");
            }
        }
    });
    return false;
}

<asp:Button runat="server" Text="Click Me" OnClientClick="return confirmPostBack(this)" />
于 2012-10-19T19:31:19.377 に答える
1

私は数ヶ月前にこの質問を解決しなければなりませんでした。フォームに複数のボタンを配置したかったのですが、おそらくキャンセルボタンに加えて、テンプレート化されたリピーターに含まれ、すべてのボタンに適切な確認を正しく要求し、フォームを送信するか、ユーザーの操作に基づいてキャンセルします。以下のコントロールは、必要に応じて何度でもフォームに含めることができます。System.Web.UI.WebControls.LinkButtonコントロールのPostbackEventReferenceを継承して使用し、確認された場合に送信するコントロールを認識します。System.Web.UI.WebControls.Button必要に応じて、コントロールは代わりに簡単に継承できます。リンクボタンを使用することにしたのは、ボタンのWebコントロールと非常によく似た動作をしますが<input type=submit>、コントロールアダプターを使用せずにjQueryUIを使用してアイコンでスタイルを設定できないものを出力しないためです。

/// <summary>
///     A <see cref="T:System.Web.UI.WebControls.LinkButton"/> with added jQuery UI functionality to provide a modal dialog box to cancel the form submit client side.
/// </summary>
/// <remarks>This class requires the inclusion of jQueryUI</remarks>
[DefaultProperty("Text")]
[ToolboxData("<{0}:jQueryUIConfirmedLinkButton runat=\"server\"></{0}:jQueryUIConfirmedLinkButton>")]
public class jQueryUIConfirmedLinkButton : LinkButton
{
    /// <summary>
    ///     Holds the postback event reference data so that the emitted client script can execute the postback if the user confirms the action.
    /// </summary>
    protected string eventReference = null;

    /// <summary>
    ///     Gets or sets the emitted dialog's ID attribute.
    /// </summary>
    /// <value>
    ///     The dialog's ID attribute.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("dialog")]
    [Localizable(true)]
    public string DialogCssID
    {
        get
        {
            String s = (String)ViewState["DialogCssID"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogCssID"] = value;
        }
    }

    internal protected string DialogID
    {
        get
        {
            return String.Format("{0}_{1}", this.ClientID, DialogCssID);
        }
    }

    /// <summary>
    ///     Gets or sets the content of the dialog. This can be plain text or HTML.
    /// </summary>
    /// <value>
    ///     The HTML or plain text content of the dialog.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("<p>Are you sure?</p>")]
    [Localizable(true)]
    public string DialogContent
    {
        get
        {
            String s = (String)ViewState["DialogContent"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogContent"] = value;
        }
    }

    /// <summary>
    ///     Gets or sets the title that will appear on the dialog.
    /// </summary>
    /// <value>
    /// The dialog's title.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("Confirm Action")]
    [Localizable(true)]
    public string DialogTitle
    {
        get
        {
            String s = (String)ViewState["DialogTitle"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogTitle"] = value;
        }
    }

    /// <summary>
    ///     Gets or sets the text that will appear on the confirmation button.
    /// </summary>
    /// <value>
    ///     The text that will appear on dialog's confirmation button.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("Yes")]
    [Localizable(true)]
    public string DialogConfirmButtonText
    {
        get
        {
            String s = (String)ViewState["DialogConfirmButtonText"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogConfirmButtonText"] = value;
        }
    }

    /// <summary>
    ///     Gets or sets the text that will appear on the dialog's rejection button.
    /// </summary>
    /// <value>
    ///     The text that appears on the dialog's rejection button.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("No")]
    [Localizable(true)]
    public string DialogRejectButtonText
    {
        get
        {
            String s = (String)ViewState["DialogRejectButtonText"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogRejectButtonText"] = value;
        }
    }

    /// <summary>
    ///     Raises the <see cref="E:System.Web.UI.Control.Load" /> event. Emits the necessary client script for the control to function.
    /// </summary>
    /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        this.eventReference = Page.ClientScript.GetPostBackEventReference(this, string.Empty);
        Page.ClientScript.RegisterStartupScript(this.GetType(), string.Format("{0}{1}", this.ClientID, "-DialogScript"), this.GetClientScript(), true);
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(), string.Format("{0}{1}", this.ClientID, "-DialogShowScript"), string.Format("function {0}Confirm() {{$('#{0}').dialog('open');}}", this.DialogID), true);
        this.OnClientClick = String.Format("{0}Confirm();return false;", this.DialogID);
    }

    /// <summary>
    ///     Renders the contents of the control to the specified writer. Adds the dialog HTML container to the output stream.
    /// </summary>
    /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter" /> object that represents the output stream to render HTML content on the client.</param>
    protected override void RenderContents(HtmlTextWriter writer)
    {
        base.RenderContents(writer);
        writer.AddAttribute("id", this.DialogID);
        writer.RenderBeginTag("div");
        writer.Write(this.DialogContent);
        writer.RenderEndTag();
    }

    public override void RenderEndTag(HtmlTextWriter writer)
    {
        base.RenderEndTag(writer);
    }

    /// <summary>
    ///     Gets the client script.
    /// </summary>
    /// <returns>A string that will be output to the client as script</returns>
    private string GetClientScript()
    {
        return string.Format(@"$(function () {{

                            $('#{0}').dialog({{
                                autoOpen: false,
                                modal: true,
                                resizable: false,
                                buttons: {{
                                    '{1}': function () {{
                                        $(this).dialog('close');
                                        eval({2});
                                    }},
                                    '{3}': function () {{
                                        $(this).dialog('close');
                                    }}
                                }},
                                title: '{4}'
                            }});
                          }});", this.DialogID, this.DialogConfirmButtonText, this.eventReference, this.DialogRejectButtonText, this.DialogTitle);
    }
}
于 2012-12-24T15:43:47.553 に答える
1

私は最近これを使用しましたが、リンクボタンでのみ機能します。必要に応じて、HTMLボタンのように見えるようにスタイルを設定できます(結局のところ、これらは単なるアンカーです)。

js

$(function () {
    $("#confirmMe").click(function (e) {
        e.preventDefault();
        var $anchor = $(this);
        $("<div>Are you sure you want to do that?</div>").dialog({
            title: "Confirm",
            modal: true,
            buttons: {
                "Ok": function () {
                    window.location = $anchor.attr("href");
                },
                "Cancel": function () {
                    $(this).dialog("close");
                }
            }
        });
    });
});

.netマークアップ([OK]をクリックするとconfirmMe_Clickイベントが発生します)

<asp:LinkButton Text="Open Me" runat="server" ID="confirmMe" 
    ClientIDMode="Static" onclick="confirmMe_Click" />
于 2012-10-20T00:07:33.573 に答える
1

これらは私の2セントで、私のプロジェクトで機能しました。

    // Initialices the behaviour when the page is ready
    $(function() {
        // Sets the function to be called when the confirmation button is pressed          
        $('.jqConfirmacionBorrar').click(function(e) {
            // Prevents the default behaviour of the button
            e.preventDefault();
            // Gets the name of the button that was clicked
            var ControlClickedName = $(this).attr('name');
            // Sets up the dialog to be called, with some custom parameters.
            // The important one is to do the postback call when the confirmation
            // button ('Aceptar' in spanish) is clicked.
            $("#DivConfirmacion").dialog({
                width: 650,
                modal: true,
                draggable: true,
                autoOpen: false,
                buttons: {
                    'Cancelar': function() {
                        $(this).dialog('close');
                        return false;
                    },
                    'Aceptar': function() {
                        $(this).dialog('close');
                        __doPostBack(ControlClickedName, '');
                        return true;
                    }
                }
            });
            // Opens the dialog to propt the user for confirmation
            $('#DivConfirmacion').dialog('open');
        });
    });
于 2013-06-15T16:37:27.453 に答える
0

私はしばらく前にこの作業を思いついたので、最新のjquery-uiダイアログプラグインでまだ最新であるかどうかはわかりませんが、一般的なアイデアは得られます。これは、(残念ながら)evalasp.netが生成するjavascriptを実行して、アンカーのhrefに配置されたフォームを送信するために使用します。アンカーにcssクラスのを与える必要がありconfirm-requiredます。

<div class="confirm-dialog ui-helper-hidden" title="Confirm">
    <span class="ui-icon ui-icon-alert"></span>
    <p>Are you sure?</p>
</div>

<script language="javascript" type="text/javascript">

$(function(){
    // call confirm dialog boxes from buttons that require it
    $(".confirm-required:isactive").click(function () {
        var callback = $(this).attr("href");
        return showConfirmDialog(callback);
    });
});

this.showConfirmDialog = function (callback) {
    $(".confirm-dialog").dialog("destroy");
    $(".confirm-dialog").dialog({
        autoOpen: true,
        modal: true,
        buttons: {
            "OK": function () {
                $(this).dialog("close");
                eval(callback);
            },
            "Cancel": function () {
                $(this).dialog("close");
            }
        }
    });

    return false;
};

</script>
于 2012-10-19T17:16:44.163 に答える
0

少し長いことは認めますが、考えられるすべてのケースで次のように機能します。

$(document).ready(function () {
    'use strict';
    var getParsedPostback = function getParsedPostback(self) {
        /*
         * self is a jQuery object. The purpose of this function is to extract the
         * __doPostBack function or the WebForm_DoPostBackWithOptions function as a
         * string, parse out the component arguments, and return it as a different
         * function to be used as a callback. If the postback function does not exist
         * as a string (in the case of a submit button, for instance) then the
         * returned callback should unbind any click handlers and then trigger the
         * element's click event.
         */
        var postback = self.data('postback'),
            trimLeft = /^\s+/,
            trimRight = /\s+$/,
            startingQuote = /^['"]/,
            endingQuote = /['"]$/,
            eventTarget,
            eventArgument,
            validation,
            validationGroup,
            actionUrl,
            trackFocus,
            clientSubmit;
        if (postback.substring(postback.length - 1, postback.length) === ';') {
            //remove the trailing ";"
            postback = postback.substring(0, postback.length - 1);
        }
        if (postback.indexOf('javascript:') === 0) {
            //remove the "javascript:"
            postback = postback.substring(('javascript:').length, postback.length - 1);
        }
        //in case postback is in the form __doPostBack(&#39;XXXXXX&#39;,&#39;XXXXXX&#39;)
        postback = decodeURIComponent(postback);
        //parse by case
        if (postback.indexOf('__doPostBack(') === 0) {
            //postback should now be __doPostBack('XXXXXX','XXXXXX')
            postback = postback.substring(('__doPostBack(').length, postback.length - 2);
            postback = postback.split(',');
            eventTarget = encodeURIComponent(postback[0].replace(startingQuote, '').replace(endingQuote, ''));
            eventArgument = encodeURIComponent(postback[1].replace(startingQuote, '').replace(endingQuote, ''));
            postback = function () {
                __doPostBack(eventTarget, eventArgument);
            };
        } else if (postback.indexOf('WebForm_DoPostBackWithOptions(') === 0) {
            //postback should now be WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions('XXXXXX', 'XXXXXX', 'XXXXXX', 'XXXXXX', 'XXXXXX'))
            postback = postback.substring(('WebForm_DoPostBackWithOptions(').length, postback.length - 2);
            postback = postback.split(',');
            eventTarget = encodeURIComponent(postback[0].replace(startingQuote, '').replace(endingQuote, ''));
            eventArgument = encodeURIComponent(postback[1].replace(startingQuote, '').replace(endingQuote, ''));
            validation = !!postback[2].replace(startingQuote, '').replace(endingQuote, '');     //use !! to convert string to boolean
            validationGroup = encodeURIComponent(postback[3].replace(startingQuote, '').replace(endingQuote, ''));
            actionUrl = encodeURIComponent(postback[4].replace(startingQuote, '').replace(endingQuote, ''));
            trackFocus = !!postback[5].replace(startingQuote, '').replace(endingQuote, '');     //use !! to convert string to boolean
            clientSubmit = !!postback[6].replace(startingQuote, '').replace(endingQuote, ''); //use !! to convert string to boolean
            postback = function () {
                __doPostBack(new WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit));
            };
        } else if (postback === 'submit') {
            //no apparent postback handler, must be a submit or an image
            postback = function () {
                //unbind the assigned click handler
                self.unbind('click');
                //trigger the click event
                self.click();
            };
        }
        return postback;
    };
    var clickHandler = function clickHandler(e) {
        var postback = getParsedPostback($(this)); //get the postback as a callback
        $('div#dialog').dialog('option', {
            "buttons": {
                "Delete all items": function () {
                    $(this).dialog('close');
                    postback(); //call the postback
                },
                "Cancel": function () {
                    $(this).dialog('close');
                }
            }
        }).dialog('open');
        e.preventDefault();
        return false;
    };
    var storePostbacks = function storePostbacks() {
        /*
         * The purpose of this function is to remove any existing __doPostBack functions
         * or WebForm_DoPostBackWithOptions functions and store them in the "data" for
         * the element. The "getParsedPostback" function above wil make extensive use of
         * the element's "data" to parse a usable callback for postback.
         */
        $('input[type="submit"], input[type="button"], input[type="image"], a[href*="__doPostBack"]').each(function (i, elem) {
            var self = $(elem),
            postback = '';
            if (typeof self.attr('onclick') !== 'undefined') {
                //store the postback in data and remove from the element.
                postback = self.attr('onclick');
                self.removeAttr('onclick').data('postback', postback);
            } else if (typeof self.attr('href') !== 'undefined') {
                //store the postback in data and remove from the element.
                postback = self.attr('href');
                self.attr('href', '#').data('postback', postback);
            } else if (self.attr('type') === 'submit' || self.attr('type') === 'image') {
                //flag as a submit.
                self.data('postback', 'submit');
            }
        });
    };
    storePostbacks();
    $('input#<%#aspButton1.ClientID %>').click(clickHandler);
    $('input#<%#aspButton2.ClientID %>').click(clickHandler);
    $('input#<%#aspImageButton.ClientID %>').click(clickHandler);
    $('a#<%#aspLinkButton.ClientID %>').click(clickHandler);
    $('div#dialog').dialog({
        "autoOpen": false
    });
});

ASP.Net 4.0FrameworkとjQuery1.8.2およびjQueryUI1.9.0を使用して、次のマークアップでテストしました。

<body>
    <form id="form1" runat="server">
    <div>
        <div id="dialog">
            <p>Test of dialog.</p>
        </div>
        <div id="controls">
            <asp:Button ID="aspButton1" runat="server" Text="aspButton1" />
            <asp:LinkButton ID="aspLinkButton" runat="server">LinkButton</asp:LinkButton>
            <asp:ImageButton ID="aspImageButton" runat="server" />
            <asp:Button ID="aspButton2" runat="server" Text="aspButton2" />
        </div>
    </div>
    </form>
</body>
于 2012-10-20T16:46:56.863 に答える