Validación de Formularios: Cómo cancelar la ejecución de un evento

Lo primero que hay que aclarar es cuándo se necesita cancelar un evento. Supongamos que queremos evitar que se procese un formulario si es que no se completaron todos los datos. En ese caso deberíamos cancelar el evento “submit” una vez que verificamos que no se cumplen todos los requisitos. Muchas veces por no saber cómo cancelar un evento se verifican los valores del formulario al presionar un botón cualquiera, pero eso obliga a que se deba apretar ese botón para procesar el formulario, cuando en realidad apretando al tecla enter sobre cualquiera de sus componentes basta.El primer problema que debemos afrontar es la diferente forma de manejar los eventos entre el estándar W3C implementado por todos los navegadores menos Internet Explorer.

La primera cuestión es cómo obtener el objeto evento. El estándar de W3C indica que se recibe como primer parámetro de la función que maneja el evento mientras que Internet Explorer lo pone como un objeto global accesible mediante la propiedad event del objeto window.

La segunda cuestión es la cancelación es sí. El estándar incluyó un método preventDefault() en el objeto event, mientras que IE prefiere que la función que maneja el evento retorne false para indicar que se va a cancelar.

Más allá de que debemos contemplar ambas implementaciones, podemos analizar sus ventajas y desventajas. En el primer caso, el uso de una variable global para obtener el evento es algo muy problemático. Por ejemplo, ¿qué valor tiene esa variable si la accedemos cuando no se está procesando ningún evento?, o ¿qué pasa si asignamos un valor a esa variable? Todos esos problemas se evitan con la forma especificada en el estándar W3C. En el segundo caso, la forma de cancelar un evento, vemos que es mucho más claro invocar un método en el propio evento que devolver el valor false desde la función que lo maneja. Además recordemos que un evento puede tener muchas funciones manejadoras con lo que cada una tendrá un valor de retorno, pero todas manejarán el mismo evento.

<html>
<head>
<script type="text/javascript">
/*
e es el evento,
f es el formulario
*/
function check(e, f){
    // forma estándar (soportada por Mozilla firefox y por IE 6) de acceder a los
    // campos de formulario por su nombre (name).
    if(f.elements.namedItem("username").value == "" || f.elements.namedItem("password").value == ""){
        // mostrar cartel
        alert("Ingrese los datos requeridos");
        if(e.preventDefault){
            // forma estandar de evitar el submit.
            e.preventDefault();
        }else{
            // forma de IE de evitar el submit
            e.returnValue = false;
        }
    }
}
</script>
</head>
<body><!--
Miren como invoco la función check, pasándole como 1er parámetro el evento con ese nombre: event
El segundo parámetro es el formulario, para comodidad.
El action y el enctype son de ejemplo, pongan ahí lo que quieran.
-->
<form action="mailto:nadie@pepito.com" method="POST" enctype="text/plain" onsubmit="check(event, this)">
<input type="text" name="username" />
<input type="text" name="password" />
<input type="submit" />
</form>
</body>
</html>

Si miran el ejemplo es un formulario con dos campos de texto al que le especificamos una función para manejar el evento submit mediante el atributo onsubmit. La idea es cancelar la ejecución de ese evento si no se verifica que ambos campos tengan algo escrito.

En la función check el objeto evento se recibe como primer parámetro y el formulario como segundo. Para que eso funcione en IE debemos enviarlo nosotros en la invocación. Si los campos del formulario no se completaron con algo, debemos cancelar el evento según con qué navegador se está visualizando la página. Para eso sirve el if que dice “if(e.preventDefault)”. En IE esa propiedad no existe y la condición es falsa. En un navegador que implemente el estándar esa propiedad contiene la función para cancelar el evento y la condición será verdadera.

Por suerte IE tiene algo rarísimo que nos simplifica la tarea: se le puede asignar al objeto event el valor que deseamos que retorne la función. Entonces en lugar de retornar false lo asignamos a la propiedad returnValue de ese objeto.

Hay varias cosas a destacar:

  • Nunca preguntamos por el nombre del navegador ni su versión sino que verificamos la presencia o ausencia de la funcionalidad que necesitamos. Esa es una técnica muy útil y más robusta que la de preguntar por el nombre del navegador.

  • La solución funciona en todos los navegadores. En particular con Firefox, Opera e Internet Explorer 6.

  • No perdemos la capacidad de enviar el formulario presionando enter en cualquiera de sus campos. Es muy común que cuando se le agrega validación a los formularios web se les quita esa funcionalidad, pero esta técnica asegura su mantenimiento de forma natural y sin esfuerzo.

  • Minimizamos la cantidad de código específico para los browsers no estándar. Eso simplifica el mantenimiento de la página.

Oracle 9 Sin Estadísticas

Si administrás una base de datos Oracle versión 9, calculá las estadísticas de todos los objetos y bastante seguido.

Cuando Oracle arma el plan de ejecución, si no tiene estadísticas para alguna tabla y sí tiene para otra, estima a grosso modo las que no están y el plan resultante es una basura que terminará leyendo muchísimos bloques innecesariamente.

En mi experiencia, un query que actuaba sobre una tabla de millones de registros pasó de 48 horas a 2 horas sólo por el cálculo de las estadísticas. Es especialmente importante cuando se hacen consultas que involucran joins.

Además, el cálculo de las estadísticas no interfiere con otras operaciones y puede ser programado para realizarse en los momentos en que no se está usando y se puede dividir por particiones y por esquema para distribuir el cálculo en el tiempo.