Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

unidades:08_formularios:03_mensajes [2014/08/27 21:35]
admin
unidades:08_formularios:03_mensajes [2014/10/22 16:59] (actual)
admin [El botón de Submit]
Línea 4: Línea 4:
 </​note>​ </​note>​
  
 +<​note>​
 +Personalmente tengo que decir que no me gusta lo que voy a explicar en este tema sobre mostrar mensajes al usuario ya que implica repetir el texto de los mensajes , repetir etiquetas HTML , etc., pero es la forma en la que siempre lo he visto explicado.
 +
 +En proyectos reales recomiendo que te hagas tus servicios/​directivas para evitar tanta repetición.
 +</​note>​
 +
 +En los temas anteriores hemos visto cómo añadir las validaciones y cómo saber desde JavaScript las validaciones que han fallado. Ahora toca la parte de mostrar al usuario los mensajes de error. ​
 +
 +
 +La forma de mostrar los mensajes es bastante sencilla e ingeniosa. Lo que hacemos es poner todos los mensajes que necesitemos debajo de cada ''<​input>''​ o donde quieras que aparezcan y luego con la directiva ''​ng-show''​ los muestras. Veamos un ejemplo.
 +
 +<sxh html;​highlight:​ [2]>
 +Nombre:<​input type="​text"​ ng-model="​model.nombre"​ name="​nombre"​ ng-maxlength="​50"​ ng-minlength="​3"​ ng-required="​requeridoNombre"​ ng-pattern="​patternNombre"​ >
 +<span ng-show="​miFormulario.nombre.$error.maxlength">​El tamaño m&​aacute;​ximo debe ser 50</​span>​
 +</​sxh>​
 +  * Línea 2: El mensaje sólo se mostrará si ''​miFormulario.nombre.$error.maxlength==true''​ y éso sólo ocurre si realmente el valor tiene un tamaño mayor que 50.
 +
 +===== Errores al inicio =====
 +Si aplicamos este mismo patrón a la validación de ''​required''​ veremos que tiene un problema:
 +<sxh html;​highlight:​ [3]>
 +Nombre:<​input type="​text"​ ng-model="​model.nombre"​ name="​nombre"​ ng-maxlength="​50"​ ng-minlength="​3"​ ng-required="​requeridoNombre"​ ng-pattern="​patternNombre"​ >
 +<span ng-show="​miFormulario.nombre.$error.maxlength">​El tamaño m&​aacute;​ximo debe ser 50</​span>​
 +<span ng-show="​miFormulario.nombre.$error.required">​El campo es requerido</​span>​
 +</​sxh>​
 +  * Línea 3: Nada más mostrar el formulario ya aparece el mensaje de "El campo es requerido"​ ya que no hay nada en el campo. ​
 +
 +Queda un poco feo mostrar un mensaje de error cuando aún no ha empezado ni a escribir nada , por eso para ese tipo de validaciones se suele añadir la condición ''&&​ miFormulario.nombre.$dirty''​ . Es decir que el usuario haya escrito por lo menos algo en ese campo.
 +
 +<sxh html;​highlight:​ [3]>
 +Nombre:<​input type="​text"​ ng-model="​model.nombre"​ name="​nombre"​ ng-maxlength="​50"​ ng-minlength="​3"​ ng-required="​requeridoNombre"​ ng-pattern="​patternNombre"​ >
 +<span ng-show="​miFormulario.nombre.$error.maxlength">​El tamaño m&​aacute;​ximo debe ser 50</​span>​
 +<span ng-show="​miFormulario.nombre.$error.required && miFormulario.nombre.$dirty">​El campo es requerido</​span>​
 +</​sxh>​
 +  * Línea 3: Ahora el mensaje "El campo es requerido"​ ya no aparece hasta que el usuario no escriba algo.
 +
 +Lo siguiente es añadir el resto de mensajes a todos los campos. ​
 +
 +===== Problemas =====
 +Pero si 8 campos son requeridos , deberemos escribir 8 veces cosas similares a :
 +<sxh html>
 +<span ng-show="​miFormulario.MI_CAMPO.$error.required && miFormulario.MI_CAMPO.$dirty">​El campo es requerido</​span>​
 +</​sxh>​
 +Siendo "​MI_CAMPO"​ el nombre de cada uno de los 8 campos.
 +
 +¿No es realmente una mala práctica hacer ésto?
 +
 +Luego hay otro problema, ¿como era el mensaje del tamaño máximo? Era: "El tamaño máximo debe ser 50"​. ​
 +
 +Si nos fijamos hemos puesto "a piñon"​ el valor de 50. Seguro que tarde o temprano el atributo ''​ng-maxlength''​ lo cambiaremos a otro valor , por ejemplo 40, y no nos damos cuenta de cambiar el mensaje.
 +
 +¿No debería poder sacarse ese 50 del valor del atributo ''​ng-maxlength''? ​
 +
 +En Java en [[http://​jcp.org/​en/​jsr/​detail?​id=303|JSR 303: Bean Validation]] si que se hacen cosas así y están resueltos los 2 problemas. ¿Porque no lo están en AngularJS de forma estándar?
 +
 +Si alguien cree que estoy equivocado en mi planteamiento estaría encantado de conocer sus argumentos :-)
 +
 +===== El botón de Submit =====
 +Lo normal en cualquier formulario es tener un botón para enviar los datos. Hay otro patrón que suele usarse en este caso y que es deshabilitar el botón hasta que el formulario sea válido. Por suerte es tan sencillo como:
 +
 +<sxh html;​highlight:​[1]>​
 +<button ng-click="​enviar()"​ ng-disabled="​miFormulario.$invalid"​ >​Enviar</​button>​
 +</​sxh>​
 +  * Línea 1: el botón está deshabilitado si ''​miFormulario.$invalid===true''​.
 +
 +Vemos que de forma simple evitamos que se envíen datos sin validar en el cliente.
 +
 +A esto hay que añadir otra cosa en la función ''​enviar()''​ de JavaScript.
 +
 +<sxh js;​highlight:​ [2]>
 +  $scope.enviar=function() {
 +    if ($scope.miFormulario.$valid) {
 +      alert("​Los datos aqui se habrían enviado al servidor ​ y estarían validados en la parte cliente"​);​
 +    }else {
 +      alert("​Hay datos inválidos"​);​
 +    }
 +  }
 +</​sxh>​
 +  * Línea 2: En la propia función se debe comprobar si el formulario es válido.
 +¿Porque comprobarlo en la función de ''​enviar()''?​ Porque quizás acabemos poniendo en el interfaz de usuario alguna otra forma de llamar a ''​enviar()''​ y se nos olvida comprobar en ese nuevo interfaz de usuario si el formulario es válido . Así que mejor comprobarlo siempre justo en el último sitio antes de enviar los datos, que es la función ''​enviar()''​.
 +
 +===== Otros patrones =====
 +Hay mas patrones en los formularios como que solo aparezcan los mensajes al pulsar el botón de enviar o solo al dejar el campo, sin  embargo no los vamos a ver en este curso. ​ :-(
 +
 +
 +===== Estilos CSS =====
 +Por último nos queda ver como aplicar estilos CSS distintos en función de las validaciones. Es el típico caso de poner el campo en rojo si el estado es inválido.
 +
 +Se podría hacer perfectamente con la directiva [[unidades:​04_masdirectivas:​10_ngclass]] que ya vimos, pero AngularJS no ofrece otra forma más sencilla.
 +
 +Podemos definir 4 clases CSS que AngularJS aplicará automáticamente a los campos:
 +  * ''​ng-valid''​
 +  * ''​ng-invalid''​
 +  * ''​ng-pristine''​
 +  * ''​ng-dirty''​
 +
 +Si definimos alguna de estas clases CSS, AngularJS las aplicará automáticamente a cualquier campo (''<​input>'',​ ''<​select>'',​ etc) cuando dichos campos estén en el estado correspondiente al estilo CSS.
 +
 +
 +Es decir que si definimos el siguiente estilo:
 +<sxh css>
 +.ng-invalid {
 +  border-color:​ red;
 +}
 +</​sxh>​
 +
 +En cuanto un campo esté en estado ''​$invalid===true'',​ AngularJS le aplicará el estilo CSS de ''​ng-invalid''​ y lo mismo con el resto de estilos.
 +
 +<​note>​
 +A mi la verdad es que no me llama mucho ya que no quiero relacionar mis estilos CSS con nombre de AngularJS. Así que prefiero seguir usando [[unidades:​04_masdirectivas:​10_ngclass]]
 +</​note> ​
 ===== Ejemplo ===== ===== Ejemplo =====
  
 {{url>​http://​embed.plnkr.co/​pkqjIO}} {{url>​http://​embed.plnkr.co/​pkqjIO}}
- 
unidades/08_formularios/03_mensajes.1409168133.txt.gz · Última modificación: 2014/08/27 21:35 por admin
Ir hasta arriba
CC Attribution-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0