从服务器端显示jQuery模式对话框

时间:2011-03-02 16:26:07

标签: .net jquery asp.net asp.net-ajax jquery-ui-dialog

这是我第一次使用jQuery对话框,所以这个问题可能有点简单,但我还没有找到答案。

当用户在文本框中输入内容(实际扫描条形码)时,我正在使用ASP.Net Ajax执行异步回发。这就像一个魅力。 现在我需要让用户在特定条件下决定两个选项。因此,我需要回发来决定是否必须显示此对话框以及它具有哪些内容。

问:如何从服务器端打开jQuery UI(模态)对话框,让用户选择一个选项,再次回发到服务器并处理此决定。

我想我需要AjaxControlToolkit.ToolkitScriptManager.RegisterClientScriptBlock来注册打开对话框的脚本,对不对?如果是,那么什么脚本会打开对话框onload?

然后我可以通过在对话框中设置AutoPostback=true控件(f.e.RadioButtons或DropDownList)并处理相应的事件来回发到服务器吗?

完成我正在尝试的最好/最简单的方法是什么?

编辑:我考虑将对话框封装到ASP.Net UserControl中并显示/隐藏它。这种方法是推荐的,还是会以任何方式与jQuery冲突?

对于这些问题,我们非常感谢您的帮助。



我的解决方案(感谢Kappa):

此链接也很有用:Using JQuery UI Dialog with ASP.Net and AJAX Update Panel以及Richard的评论。

我创建了一个UserControl作为jQuery-Dialog的容器:

对话框的ASCX:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="DialogRecurringRMA.ascx.vb" Inherits="ERP.DialogRecurringRMA" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<script type="text/javascript">
    function createDialog() {
        //setup dialog
        var source = $('#Dialog_RecurringRMA').parent();
        $('#Dialog_RecurringRMA').dialog({
            modal: true,
            resizable: false,
            autoOpen: true,
            draggable: true,
            width: 420,
            height: 200,
            title: '<%= Title %>',
            open: function (type, data) {
                $(this).parent().appendTo(source);
            }
        });
    }

    function showDialog() {
        $('#Dialog_RecurringRMA').dialog("open");
    }

    function closeDialog() {
        $('#Dialog_RecurringRMA').dialog("close");
    }

    </script>

<asp:UpdatePanel ID="UpdDialog" UpdateMode="Conditional" ChildrenAsTriggers="true" runat="server">
    <ContentTemplate>
    <div id='Dialog_RecurringRMA' style="display:none">
            <asp:RadioButtonList ID="RblApplyRmaToCharge" ValidationGroup="Dialog" runat="server">
                <asp:ListItem Value="1">Create new RMA and add it to current Charge</asp:ListItem>
                <asp:ListItem Value="2">Do not create new RMA</asp:ListItem>
            </asp:RadioButtonList>
            <asp:RequiredFieldValidator ID="NothingSelected" Display="None" ControlToValidate="RblApplyRmaToCharge" ValidationGroup="Dialog" runat="server" ErrorMessage="You have to decide whether RMA should be applied to current charge or not">*</asp:RequiredFieldValidator>
            <asp:ValidatorCalloutExtender ID="NothingSelectedExtender" BehaviorID="NothingSelectedExtender" runat="server" TargetControlID="NothingSelected" Width="250px"  PopupPosition="BottomRight"  HighlightCssClass="highlight" WarningIconImageUrl="~/images/warning.gif" CloseImageUrl="~/images/close.gif" />
            <br /><br /><br /><br />
            <asp:Button ID="BtnApply" runat="server" OnClientClick="javascript:Page_ClientValidate();if(Page_IsValid)closeDialog();" CausesValidation="true" ValidationGroup="Dialog" Text="apply selection" />
    </div>
    </ContentTemplate>
</asp:UpdatePanel>

对话框的Codebind:

Public Class DialogRecurringRMA
    Inherits System.Web.UI.UserControl

    Public Enum DialogResult As Int32
        NoResult = 0
        CreateRma = 1
        DoNotCreateRma = 2
    End Enum

    Public Event DialogClosed(ByVal dialog As DialogRecurringRMA)

    Public Property Title As String
        Get
            If ViewState("Title") Is Nothing Then
                ViewState("Title") = "RMA with this IMEI found, create anyway?"
            End If
            Return DirectCast(ViewState("Title"), String)
        End Get
        Set(ByVal value As String)
            ViewState("Title") = value
        End Set
    End Property

    Public Property CreateRmaText As String
        Get
            Return Me.RblApplyRmaToCharge.Items(0).Text
        End Get
        Set(ByVal value As String)
            Me.RblApplyRmaToCharge.Items(0).Text = value
        End Set
    End Property

    Public Property DoNotCreateRmaText As String
        Get
            Return Me.RblApplyRmaToCharge.Items(1).Text
        End Get
        Set(ByVal value As String)
            Me.RblApplyRmaToCharge.Items(1).Text = value
        End Set
    End Property

    Public ReadOnly Property Result() As DialogResult
        Get
            If Me.RblApplyRmaToCharge.SelectedIndex <> -1 Then
                Return If(Me.RblApplyRmaToCharge.SelectedIndex = 0, DialogResult.CreateRma, DialogResult.DoNotCreateRma)
            Else
                Return DialogResult.NoResult
            End If
        End Get
    End Property

    Public Sub Reset()
        Me.RblApplyRmaToCharge.SelectedIndex = -1
    End Sub

    Private Sub CloseDialog()
        ScriptManager.RegisterClientScriptBlock(Me, GetType(Page), UniqueID, "closeDialog()", True)
    End Sub

    Private Sub ShowDialog()
        ScriptManager.RegisterStartupScript(Me, GetType(Page), UniqueID, "createDialog();showDialog()", True)
    End Sub

    Public Sub OpenDialog()
        Reset()
        ShowDialog()
        Me.UpdDialog.Update()
    End Sub

    Protected Sub BtnApply_Click(ByVal sender As Object, ByVal e As EventArgs) Handles BtnApply.Click
        Page.Validate()
        If Me.Page.IsValid Then
            CloseDialog()
            RaiseEvent DialogClosed(Me)
        End If
    End Sub
End Class

尽可能简单地显示现在使用它的对话框:

Me.DialogRecurringRMA1.OpenDialog()

在我的情况下,它有点复杂,因为这里使用了Dialog-ascx:

MasterPage -> Page -> TabContainer-Panel -> UserControl -> UserControl -> Dialog

但这就像一个魅力:)

2 个答案:

答案 0 :(得分:2)

要打开已创建的jQuery UI对话框,您必须调用$("#elementId").dialog("open");命令。

因此,您的服务器端代码必须找出是否必须显示对话框,然后它必须注册JavaScript以使用该命令打开它。

编辑:

关于AutoPostback="true"问题:对于ASP.NET来说,无论你的命令是否在jQuery UI对话框内都没关系,对话框本身只有div display: none;

<强>请注意:

我不知道您是否知道,但是当您应用对话框时,接收它的元素将移动到body元素的末尾。

这意味着它将 <{1}}元素,并且内部的所有内容都不会被发回服务器(我两天前就开始了。)

要解决此问题,您必须以这种方式声明对话框:form,这样对话框仍会在表单后移动,但$("#elementId").dialog().parent().appendTo("#formId");部分会将其移回。

答案 1 :(得分:1)

您可能需要在页面中添加一些标记(存储在隐藏字段或服务器控件中)。您可以在$(document).ready()或链接中检测到这一点并执行任何操作。这必须在服务器端设置。

但是如果你试图在回发上执行不同的脚本(再次假设它是一个完整的回发),请使用ClientScriptManager.RegisterStartupScript

对于第二个问题,我的按钮是我的页面上的服务器控件,对应于用户单击“确定”或“取消”(假设对话框有两个按钮)。所以我有两个服务器端按钮;并且在代码隐藏中也有各自的事件处理程序。

它只是在回发后我必须隐藏这两个适合使用客户端javascript的按钮。但我可以通过其他javascript代码提出事件。