2012-05-07 29 views
5

tengo un UpdatePanel ASP.NET con lo siguiente:jQuery diálogo con ASP.NET UpdatePanel

<asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional"> 
<ContentTemplate> 
    <%-- jQuery dialog - Suppliers --%> 
    <div id="divSuppliers" style="display: none;"> 
     <asp:ListBox ID="lstSuppliers" runat="server" SelectionMode="Single" Rows="10" Width="100%" 
      DataValueField="SupplierID" DataTextField="SupplierName"> 
     </asp:ListBox> 
     <br /><br /> 
     <asp:Button ID="btnSelectSupplier" runat="server" Text="Select 2" OnClick="btnSelectSupplier_Click" /> 
    </div> 

    <asp:GridView ID="gvSuppliers" runat="server" AutoGenerateColumns="false" SkinID="gvSkin" 
     DataKeyNames="SupplierID" EmptyDataText="No Existing User Roles"> 
     <Columns> 
      <asp:TemplateField HeaderText="Supplier Name"> 
       <ItemTemplate> 
        <asp:Label ID="lblSupplierName" runat="server" Text='<%# Eval("SupplierName") %>'></asp:Label> 
       </ItemTemplate> 
      </asp:TemplateField> 
     </Columns> 
    </asp:GridView> 

    <asp:Button ID="btnAddSupplier" runat="server" Text="Add Supplier" 
     Visible="false" OnClick="btnAddSupplier_Click" /> 

</ContentTemplate> 
<Triggers> 
    <asp:AsyncPostBackTrigger ControlID="btnSelectSupplier" /> 
</Triggers> 
</asp:UpdatePanel> 

Muy sencillo, en realidad. Nada más que un div que utilizo para mi ventana emergente de jQuery Dialog, un control GridView de ASP.NET con una sola columna y un botón ASP.NET para las devoluciones de datos asincrónicas.

Aquí está el evento click que maneja la devolución de datos asincrónica para btnSelectSupplier.

protected void btnSelectSupplier_Click(object sender, EventArgs e) { 

    // +=+=+=+=+=+=+=+=+=+=+=+=+=+=  
    // WORKS JUST FINE 
    List<SupplierItem> suppliers = new List<SupplierItem>();  

    foreach (int i in lstSuppliers.GetSelectedIndices()) { 
     suppliers.Add(
      new SupplierItem { SupplierID = Convert.ToInt32(lstSuppliers.Items[i].Value), SupplierName = lstSuppliers.Items[i].Text }); 
     lstSuppliers.Items[i].Selected = false; 
    } 

    gvSuppliers.DataSource = suppliers; 
    gvSuppliers.DataBind(); 

    // +=+=+=+=+=+=+=+=+=+=+=+=+=+= 
    // DOES NOT WORK!! 
    string jq = "$('#divSuppliers').dialog('close');"; 

    ScriptManager sm = ScriptManager.GetCurrent(this); 
    if (sm != null && sm.IsInAsyncPostBack) { 
     ScriptManager.RegisterClientScriptBlock(
      this, typeof(Page), Guid.NewGuid().ToString(), 
      jq, true); 
    } 
} 

PROBLEMA: El GridView actualizará bien durante la devolución de datos asincrónica (ver el evento click arriba); sin embargo, jQuery Dialog se niega a cerrar (nuevamente, vea el evento anterior y donde dice NO FUNCIONA). Estoy registrando el javascript (jquery) con el ScriptManager en la página y por lo tanto debería estar ejecutando y cerrando el diálogo, pero por alguna razón no es así.

EDIT: Código que abre el cuadro de diálogo jQuery y lo hace modal.

protected void btnAddSupplier_Click(object sender, EventArgs e) { 
    lstSuppliers.ClearSelection(); 
    lstSuppliers.DataSource = Suppliers.GetAllSuppliers(); 
    lstSuppliers.DataBind(); 

    string jq = "var dlg = $('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); dlg.parent().appendTo($('form:first'));"; 

    ScriptManager sm = ScriptManager.GetCurrent(this); 
    if (sm != null && sm.IsInAsyncPostBack) { 
     ScriptManager.RegisterClientScriptBlock(
      this, typeof(Page), Guid.NewGuid().ToString(), 
      jq, true); 
    } 
} 
+0

¿Puede mostrar el código de jquery? Puedo resolver esto ... – Thulasiram

+0

El único jQuery relevante está incluido en mi código anterior (vea el código del evento click). El cierre del diálogo no funciona por alguna razón, eso es todo. – Jagd

+0

¿Ha intentado ejecutar '$ ('# divSuppliers'). Dialog ('close');' en una consola JS como Firebug o Developer Console en Safari/Chrome –

Respuesta

2

El div utilizado para el diálogo de jQuery UI debe estar fuera del UpdatePanel.

En btnAddSupplier_Click crea el diálogo y lo mueve fuera del UpdatePanel.
Después de btnSelectSupplier_Click tiene 2 divs con divSuppliers id, el movido y el received from server (el mecanismo UpdatePanel permite actualizaciones parciales de páginas mediante la reconstrucción de todo el DOM de UpdatePanel con html devuelto por el servidor).

También sugeriría utilizar console.log para ayudar con la depuración.
Añadir al cuadro de diálogo de cierre js: console.log($('#divSuppliers'))

+0

Puede tener razón sobre mover el cuadro de diálogo jQuery fuera del panel de actualización. De hecho, lo tuve así al principio, pero por alguna razón que no recuerdo lo moví dentro del panel de actualización. No lo habría movido allí sin una razón. De todos modos, tendré que hacer algunas pruebas más y ver si funciona cuando tenga algo de tiempo extra. Todavía creo que voy a arrancar la basura de .net y usar jQuery con AJAX. – Jagd

+0

Cuando se actualiza el panel de actualización, se borra todo su html y se actualiza con el contenido recibido del servidor, incluido el cuadro de diálogo div, por lo que queda 2 divs con el mismo id, el que se movió fuera y el que se recrea a partir de la actualización actualización del panel. – eitanpo

+0

Debería crear un nuevo 'divSuppliersDialog' vacío fuera del panel de actualización y usarlo para el diálogo. Deberá usar 'RegisterClientScriptBlock' para mover' divSuppliers' como elemento secundario de 'divSuppliersDialog' antes de mostrarlo (como ya lo hace). – eitanpo

1

¿Ha considerado realizar una ruta más simple y vincular un evento al botón del cliente para cerrar el cuadro de diálogo?

$(function() { 
    $('#btnSelectSupplier').click(function() { 

     $('#divSuppliers').dialog('close'); 
    }); 
}); 

El flujo sigue siendo el mismo desde la perspectiva del usuario. Hacen clic en el botón y el cuadro de diálogo se cierra. El código del lado del servidor se ejecutará después de que se cierre el diálogo, pero dado que no parece haber ninguna lógica del lado del servidor que decida si desea cerrar el diálogo o no después del clic, esto puede ajustarse a sus necesidades.

EDIT Veo tu problema. Se está ejecutando en un problema porque en lugar de abrir el diálogo existente, que está redefiniendo el cuadro de diálogo de clic:

string jq = "var dlg = $('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); dlg.parent().appendTo($('form:first'));"; 

En su lugar, se quiere definir el cuadro de diálogo en la función document.ready.

$(function() { 
    //define the div as a dialog. By default, it will not open until you tell it to 
$('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); 

}); 

En el clic, debe abrirlo como esto

$('#divSuppliers').dialog('open'); 

Una vez más, es posible que desee hacer esto lado del cliente en lugar de tratar de empujar el script en la página en el evento del lado del servidor, pero Eso depende de ti.

más simple solución completa:

$(function() { 

$('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); 

$('#btnAddSupplier').click(function() { 

    $('#divSuppliers').dialog('close'); 
}); 
$('#btnSelectSupplier').click(function() { 

    $('#divSuppliers').dialog('open'); 
}); 
}); 
+0

Esto funciona, pero solo la primera vez que hago clic en btnSelectSupplier. Si vuelvo a abrir el cuadro de diálogo (esto se hace haciendo clic en un botón diferente) y luego hago clic en el btnSelectSupplier, no cierra el cuadro de diálogo. Puse una alerta en el evento de clic de btnSelectSupplier para asegurarme de que se levanta cada vez que se hace clic en el botón y se muestra la alerta. Es casi como si el div para el diálogo de jquery no se encontrara después de la primera vez que se cerró. – Jagd

+0

Actualicé mi respuesta después de ver sus actualizaciones. Estaba redefiniendo el diálogo al hacer clic en lugar de llamar a la función .dialog ('abrir'). – Rondel

0

Así que aquí está la solución: no trate de mezclar con el ASP.NET UpdatePanel con el diálogo jQuery, porque simplemente no se llevan bien juntos.

Solo había ido en esta dirección porque pensé que me llevaría menos tiempo implementar AJAX utilizando los controles ScriptManager y UpdatePanel de .NET en lugar de hacerlo todo en jQuery. En este punto, parece que estaba equivocado, porque voy a volver y arrancar la basura de .NET y reemplazarla por jQuery. Así que todo ese tiempo que pensé que salvaría se ha ido como el viento.

Moral de la historia: no mezcles los dos si no tienes que hacerlo.

Cuestiones relacionadas