Evitar PostBack en un botón html runat=server Fecha: 18/Nov/2004 (11/11/04)
|
A menudo en las aplicaciones Web resulta necesario realizar validaciones del lado del cliente antes de hacer el submit de una página, de forma tal de evitar que se ejecute un roundtrip cuando no se cumple determinada condición.
Supongamos el caso más simple: deseamos que el botón “Aceptar” de nuestra página muestre un mensaje de confirmación antes de proceder a ejecutar el código en el servidor.
En primer lugar, para que un botón ejecute código javascript, el mismo no puede ser un Asp Button, dado que éste se traduce a Html en un <INPUT type=submit>, por lo cual al presionarlo siempre se hace ejecuta código en el servidor. Esto nos conduce a que debamos trabajar directamente con un botón Html <INPUT type=button>, el cual debe además correr del lado del servidor:
<INPUT type="button" value="Aceptar" id="Button1" name="Button1" runat="server">
Ahora, al utilizar un botón Html, ponemos a Asp.Net en un aprieto, dado que debe encontrar una forma de hacer que este botón vaya al servidor cuando se lo presiona, dado que le pusimos runat=server. Veamos cómo se las arregla para lograr esto.
Si ejecutamos la página que contiene ese botón en un Explorador Web, y vemos el código que generó Asp.Net para ese botón, nos encontramos con lo siguiente:
<input language="javascript" onclick="__doPostBack('Button1','')" name="Button1" id="Button1" type="button" value="Aceptar" />
Vemos que se ha colocado automáticamente un evento onClick que tiene una llamada a una función “__doPostBack(..)”, que además recibe dos parámetros. Podemos ver la definición de esta función más arriba en esa misma página:
<script language="javascript" type="text/javascript">
<!--
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
theform = document.Form1;
}
else {
theform = document.forms["Form1"];
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
// -->
</script>
Este código es generado por Asp.Net para asegurarse que luego de presionarse nuestro botón, se haga un submit de la página, lo cual permitirá ejecutar código en el servidor. Esto resulta bastante molesto a nuestros fines, dado que si nosotros colocamos código javascript en el evento “onclick” del botón, siempre tendremos al final la llamada a la función “__doPostBack(..)”.
Supongamos que nuestra función de validación es algo tan simple como lo que sigue:
<script language="javascript">
<!--
function Validar()
{
if (confirm('¿Confirma que desea aceptar?'))
{
return true;
}
else
{
return false;
}
}
//-->
</script>
Para poder ejecutar esta validación al presionar nuestro botón, debemos hacer una llamada a la función en el evento “onclick”, de la siguiente forma:
<input language="javascript" name="Button1" id="Button1" type="button" value="Aceptar" onclick="Validar();" />
Pero cuando corramos la aplicación, nuestro querido Asp.Net nos agregará el código que vimos antes, y quedaría así:
<input language="javascript" name="Button1" id="Button1" type="button" value="Aceptar" onclick="Validar(); __doPostBack('Button1','')" />
Una nota antes de seguir: debe tenerse en cuenta que si no ponemos punto y coma luego del llamado a nuestra función “Validar()”, obtendremos un error, dado que la sintaxis del evento “onclick” quedaría errónea luego de que Asp.Net nos agregue la función “__doPostBack(..)”.
Más allá de ese detalle, nuestro verdadero problema es otro: ¿cómo evitar que nuestro botón termine haciendo un submit cuando nuestra validación es falsa?. Es decir, si el usuario, ante la pregunta “¿Confirma que desea aceptar?” contesta que no, nosotros no debemos permitir que la ejecución pase al servidor, sino quedarnos en el cliente para que el usuario haga las correcciones necesarias, y así nos ahorramos un roundtrip innecesario.
Aquí viene la solución mágica. En nuestra llamada a la función, debemos poner lo siguiente:
<input language="javascript" name="Button1" id="Button1" type="button" value="Aceptar" onclick="if (Validar()) " />
Para quienes aún no captaron la idea, les explico. Al poner “if (Validar()) “, nuestro código quedará de la siguiente forma luego de que Asp.Net genere su agregado:
<input language="javascript" name="Button1" id="Button1" type="button" value="Aceptar" onclick="if (Validar()) __doPostBack('Button1','')" />
De esta forma, si nuestra función de validación devuelve verdadero, se ejecutará la función “__doPostBack(..)”. En cambio, si la validación devuelve falso, no se cumplirá la condición del if, por lo que no se ejecutará el llamado a dicha función.
Simple, ¿no es así?. Pruébenlo y verán que funciona. Algunos pensarán que la solución no es del todo elegante, dado que en tiempo de diseño nos queda una “sentencia extraña” en el código del evento onclick. Pero bueno, tampoco es elegante que Asp.Net nos genere funcionalidad en tiempo de ejecución. Sin embargo, así es como la cosa funciona.
Hasta la próxima.