Validación no obstrusiva

Validacion
¿ Obstrusiva u Obstructiva ? … la dos palabras aparecen subrayadas en rojo por mi editor.
De todas maneras, para no complicarnos con palabras difíciles, vamos a decir que intentaremos lograr hacer un formulario web cuya validación no vuelva loco al usuario, sin por ello dejar de controlar la calidad de los datos que se ingresen.
Durante años sentí que la parte mas fastidiosa del desarrollo de una aplicación es la validación de los formularios.
No puedo evitar tener pensamientos tales como: “Si no fuera porque algún f%u@c#king usuario que mete cualquier m@i#e@*rda en los formularios y me hace volar el sistema por el aire… esto ya estaría listo, la rep€#ut@&%ma madre que los re mil ….”.
Después de un rato, respiro hondo, cuanto hasta diez y me pongo a trabajar.

Dicen que hay veces que la inspiración viene de la bronca, y creo que este es el caso.
Me canse de validar una y mil veces las mismas cosas, así que metí en cada control del Framework una validación implícita de formato, de acuerdo al tipo que permita editar (numérico, fecha, lista, etc.)
Otra, común a la mayoría de los controles, que verifica rangos de valor y control de vacío. Y una última que tiene que ver con los controles enlazados a datos, verificando la existencia o no de un dato en una tabla SQL.
Todo esto de manera tal que el desarrollador no deba escribir una gota de código Javascript.
Por si esto no alcanzara, cada control expone un evento ‘Validando’ que puede correr una función que controle de manera personalizada el dato ingresado.

<MM2:Combo ID="Empleado_AlMo_Country" IdDatos="Paises" Descripcion="Descripcion"
   Valor="Codigo" CssError="Invalido" AceptaBlanco="false" Validando="ValidandoPais"
   runat="server">
</MM2:Combo>
 function ValidandoPais(sender, e) {
  if (e.Valor == "AR") {
    e.Mensajes.push("el valor no puede ser Argentina");
    e.Erroneo = true;
  }
}

Aquí vemos un ejemplo de control Combo que no acepta valores en blanco y a su vez es validado por una rutina en Javascript (ValidandoPais) que no permite el ingreso del Valor “AR”.
Pasar la descripción del error es tan fácil como hacer un push dentro de la lista de mensajes de error, para luego signar al control como erroneo.

Nunca se restringe el movimiento del usuario por todo el Formulario.
Puede ir y venir cuantas veces quiera usando teclado y mouse a la vez, obteniendo carteles informando los errores pero en ningún momento se impedirá su desplazamiento.
El control Formulario quedó sincronizado con los controles que contiene, y no es posible enviar ningún dato al servidor que no pase su propia validación mas la del Formulario.
Cada control agrega al documento automáticamente un span con un ul dentro.
Este último se llenará con los mensajes de error, apareciendo y desapareciendo según corresponda.
Solo deberemos aplicar a este span un Css adecuado para que la apariencia tenga que ver con nuestro diseño.

Como el ejemplo siguiente:


span ul
{
    margin: 0px 0px 0px 0px;
}

.Invalido
{
    background-color: #ECF2F9;
}


.Invalido + span
{
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    
    margin-top : -30px;
    margin-left : -15px;
    padding : 3px 6px 3px 0px;
    position: absolute;
    z-index: 1100;
    white-space: nowrap;
    border: 0px solid #FF0000;
    background-color: #FFFFDD;
    box-shadow: 0px 0px 10px rgba(0,0,0,.5);
    -webkit-filter: drop-shadow(0px 0px 10px rgba(0,0,0,.5));
    -moz-filter: drop-shadow(0px 0px 10px rgba(0,0,0,.5));
    -ms-filter: drop-shadow(0px 0px 10px rgba(0,0,0,.5));
    -o-filter: drop-shadow(0px 0px 10px rgba(0,0,0,.5));
    filter: drop-shadow(0px 0px 10px rgba(0,0,0,.5));
    filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=5, OffY=5, Color='gray', Positive='true');
}

.Invalido + span:after
{
    content: ' ';
    border: solid 10px transparent;
    border-bottom: 0;
    border-top-color: #FFFFDD;
    display: block;
    position: absolute;
    margin-top :2px;
    z-index: 1101;
   
}

Suponiendo que nuestros controles usen la clase .Ivalido para colorease cuando se encuentre en estado Erroneo. Podemos configurar los mensajes de error otorgando estilo al span que esta inmediatamente a la derecha de este. Esto lo hacemos con la directiva +.

Ej: .Invalido + span { …. }

En este ejemplo yo hice unos cartelitos del tipo globo que se ven muy bien en Chrome o Firefox.
Ustedes pueden usar su destreza e imaginación para hacer, seguramente, cosas inimaginables.

Para los que gusten saber un poco mas en profundidad los detalles de las técnicas de programación utilizadas en este Framework, les comento que hubo que desarrollar un especie interface en Javascript para que todos los controles implementarán.
Como todos saben Javascirpt no posee naturalmente herencia y/o interfaces, pero sí es posible simularlas.
Este es nuestro caso. Todos los controles, al momento de inicializarse, invocan la implementación de la interfaz de Validación.
Esta interfaz no es mas que un método que agrega al control los elementos necesarios para que luego, en el momento de validar, todo esté listo para recibir los datos del caso y obrar en consecuencia.
De esta manera nos aseguramos que todos los controles del Framework validen de la misma forma, los agregados o cambios futuros quedan centralizados en la interfaz y si hay nuevos controles, validen exactamente de la misma forma que los anteriores.

Una vez validado cada uno de los controles, se corre una validación a nivel formulario del lado del cliente. Esta función nos permitirá una segunda oportunidad de controlar los valores antes de viajar al servidor. Aquí podremos, por ejemplo, comparar el valor de dos o mas controles. En nuestro código advertimos que el salario en EEUU no debería ser menor a 75000 dólares. Y lo hacemos de la siguiente manera:

function ValidandoFormulario(sender, e) {
   if (e.Valores.Country == "USA" && e.Valores.Salario < 75000) {
       e.Mensajes.push("En EEUU el salario no puede ser menor a u$s 75000");
       e.Erroneo = true;
   }
}

Simplemente capturamos el evento Validando del formulario para que ejecute la función ValidandoFormulario.
Podemos ver un parámetro e que contiene todos los valores del formulario que acaban de ser ingresados por el usuario.
Si algún valor no satisface la validación simplemente hacemos un push en la propiedad Mensajes del parámetro e con el mensaje al usuario, para luego signar este último como erroneo.

Como última oportunidad de validar tendremos la opción de consultar los valores que llegan al servidor en nuestro codebehind, y antes de hacer ninguna grabación en nuestras tablas, podremos disparar un error de la siguiente manera:

<WebMethod()> _
Public Shared Function ManejoEmployees(ByVal pContrato As MoniMisi2.ProveedorDatosServidor.Contrato) As MoniMisi2.ProveedorDatosServidor.Contrato
    Dim Contrato As MoniMisi2.ProveedorDatosServidor.Contrato = pContrato
    'En Contrato.Operacion encontraremos los datos que nos envia el cliente
    'En Contrato.Metodo encontraremos los datos que viajan al cliente.
    Dim Employees As New NorthWindTableAdapters.EmployeesTableAdapter
    If Contrato.Operacion.Nombre = "Leer" Then
      Contrato = ProveedorDatosServidor.LeerFilas(Contrato, Employees.Adaptador(pContrato.Orden))
    Else
      'Aqui se harían las validaciones y/o grabaciones.
      'Si necesitamos enviar un mensajes de error lo haremos de esta manera:
      Dim Mensajes As New List(Of String)
      Mensajes.Add("error de validación en servidor 1")
      Mensajes.Add("error de validación en servidor 2")
      Mensajes.Add("etc.")
      Throw New ProveeedorDatosException(Mensajes)

    End If
    Return Contrato
End Function

De esta manera si los valores recién arribados al servidor no son de nuestro agrado, dispararemos una Excepción del tipo ProveeedorDatosException con una lista de mensajes que serán presentados del lado del cliente al usuario final.

Para mejor entendimiento les recomiendo vean el Demo en Vivo de la Validacion cuyo link también figura bajo el título DEMO EN VIVO en el panel izquierdo del blog.

Y si les gustó pueden bajarlo de la sección de BAJATE EL DEMO en el mismo panel.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s