jQuery, UpdatePanel y Postbacks

.Net, jQuery Add comments

Esto de jQuery se esta convirtiendo en un vicio (compite mano a mano con Silverlight) y conforme más juegas más quieres y más te diviertes. Y si añadimos UpdatePanels, nos divertimos aún más si cabe.

Al usar jQuery, seguramente usaremos el evento Ready para añadir manejadores de eventos, añadir efectos, añadir / quitar clases.... en fin, inicializar los controles de nuestra página.  El evento Ready de jQuery  es un evento que se lanza una vez que todo el DOM de la página ha sido cargado por completo. Por otro lado tenemos los postback parciales provocados por los updatePanels. El cometido de estos controles es evitar la carga completa de la página, es decir, solo actualizar aquellos controles contenidos en el control UpdatePanel. Pero lo que hace realmente no es actualizar los valores de los controles, sino que los sustituye  por otros nuevos, tras lo cual todos los controles que hay en el UpdatePanel perderán las clases y eventos asociados a ellos en la inicialización de la página. Esto incluye tanto controles de servidor como controles de cliente, todos serán reemplazados.

Por ejemplo tomemos como ejemplo este UpdatePanel y controles:

Â

HTML:
  1. <asp:UpdatePanel ID="UP" runat="server">
  2.         <ContentTemplate>
  3.             <table>
  4.                 <tr>
  5.                     <td width="40px">
  6.                         <span class="label8">Nombre: </span>
  7.                     </td>
  8.                     <td width="40px">
  9.                         <input type="text" id="txtnombre" class="inputText" />
  10.                     </td>
  11.                     <td width="80px">
  12.                         <asp:TextBox runat="server" ID="lblNombre"/>
  13.                     </td>
  14.                 </tr>
  15.                 <tr>
  16.                     <td>
  17.                         <span class="label8">Direccion: </span>
  18.                     </td>
  19.                     <td>
  20.                         <input type="text" id="txtDireccion" class="inputText" />
  21.                     </td>
  22.                     <td>
  23.                         <asp:TextBox runat="server" ID="lblDireccion"/>
  24.                     </td>
  25.                 </tr>
  26.                 <tr>
  27.                     <td>
  28.                         <asp:Button runat="server" ID="btnAceptar" Text="Aceptar"
  29.                             CssClass="btnMandatory" onclick="btnAceptar_Click"/>
  30.                     </td>
  31.                 </tr>
  32.             </table>
  33.         </ContentTemplate>
  34.    </asp:UpdatePanel>

 La inicialización de la página la llevaríamos a cabo normalmente así:

JavaScript:
  1.        $(document).ready(function () {
  2.             // Inicializacion de controles
  3.  
  4.        });

De esta manerá todo funciona correctamente, pero solo mientras no pulsemos el botón "Aceptar" que provoca el postpack parcial. Una vez hagamos click, todos los eventos asociados a los controles desaparecerán. Para solucionarlo tenemos que reasignarlos nuevamente, y una forma de hacerlo es añadiendo un manejador al evento que controla cuando un postback asíncrono ha finalizado. Nuestro código podría quedar así:

JavaScript:
  1. Sys.WebForms.PageRequestManager.getInstance().add_endRequest(Load);
  2.  
  3.         $(document).ready(function () {
  4.             Load();
  5.         });
  6.  
  7.         function Load() {
  8.             $('#' + '<%=btnAceptar.ClientID %>').attr('disabled', true);
  9.             $('#' + '<%=lblNombre.ClientID %>').attr('readonly', true);
  10.             $('#' + '<%=lblDireccion.ClientID %>').attr('readonly', true);
  11.  
  12.             $(".inputText").blur(function () {
  13.                 $(this).css("background-color", "FFFFFF");
  14.             });
  15.  
  16.             $(".inputText").focus(function () {
  17.                 $(this).css("background-color", "CCCCCC");
  18.             });
  19.  
  20.             $(".inputText").keyup(function () {
  21.  
  22.  
  23.                 if ($(this).val() == '')
  24.                     $('#' + '<%=btnAceptar.ClientID %>').attr('disabled', true);
  25.                 else {
  26.                     var nodata = false;
  27.                     $.each($(".inputText"), function () {
  28.                         if ($(this).val() == '')
  29.                             nodata = true;
  30.                     });
  31.                     $('#' + '<%=btnAceptar.ClientID %>').attr('disabled', nodata);
  32.                 }
  33.  
  34.             });
  35.  
  36.             $('#' + '<%=btnAceptar.ClientID %>').click(function () {
  37.                 $('#' + '<%=lblNombre.ClientID %>').attr('value', $("#txtnombre").val());
  38.                 $('#' + '<%=lblDireccion.ClientID %>').attr('value', $("#txtDireccion").val());               
  39.             });
  40.         } 

Lo que hemos hecho es envolver todo el código que teníamos en el evento Ready de jQuery en una función, y llamar a esta función tanto en el evento Ready, como cuando el postback asincrono del updatePanel ha terminado.

Una segunda opción sería Inyectar un script desde servidor que invoque a esta nueva función.

C#:
  1. protected void btnAceptar_Click(object sender, EventArgs e)
  2.  {
  3.         lblNombre.Text = lblNombre.Text + "--&gt; Validado con Exito";
  4.         lblDireccion.Text = lblDireccion.Text + "--&gt; Validado con Exito";
  5.         ScriptManager.RegisterStartupScript(this, GetType(), "", "Load();", true);
  6.  }

5 Responses to “jQuery, UpdatePanel y Postbacks”

  1. andres Says:

    Super… muchas gracias me salvo de una muy grande y me ayudo a comprender mejor el codigo…..

  2. Cristina H Says:

    Con la versión 1.4.4 más sencillo utilizar el método .live() http://api.jquery.com/live/

  3. Oscar Alvarado Says:

    Hola Jose Almoguera, tengo un problema con jquery y asp respecto a los postback de un updatepanel, te expongo mi problema:
    Resulta que tengo un menu en jquery con animacion con enlaces de tipo linkbutton en una master con un ContentPlaceHolder en el que carga un texto, lo q pasa es que cuando le doy al boton en el menu jquery se actualiza toda la pagina y los estados q tiene el menu no se muestran, como puedo solucionar esto, el ContentPlaceHolder esta dentro de un updatepanel, haber si me hechas una mano y me das una idea. gracias!

  4. admin Says:

    Hola creo que el problema lo tienes en el control Linkbutton de la Master Page, ya que al hacer click realizar un redirect hacia una pagina, es decir un postback, un reset completo de la pagina. Para poder controlar eso creo que no te queda mas remedio que reestrablecer el estado de tus objetos en cliente (jquery). Ten en cuenta que todo lo que sea postback (ya sea con UpdatePanel o sin el) implica una recreacion del html de la pagina, por lo que debes forzar su reinicio.

  5. KennyQuevedo Says:

    He incluido el codigo para solucionar el problema de perder la funcionalidad del jquery luego de un postback asincrono, pero al momento de cargar la pagina, al cargar por primera vez me sale el mensaje de error Sys no esta definido. He probado con algunas referencias en el web.config, algunas propiedades del toolkitscriptmanager pero me sigue saliendo… como has evitado este problema ?
    estoy utlizando Framework 4.0 asp.net

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Acceder

Switch to our mobile site