Muestra las diferencias entre dos versiones de la página.
unidades:08_formularios:03_mensajes [2014/08/27 22:18] admin |
unidades:08_formularios:03_mensajes [2014/10/22 16:59] (actual) admin [El botón de Submit] |
||
---|---|---|---|
Línea 5: | Línea 5: | ||
<note> | <note> | ||
- | Personalmente tengo que decir que no me gusta lo que voy a explicar en este tema sbore 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. | + | 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. | En proyectos reales recomiendo que te hagas tus servicios/directivas para evitar tanta repetición. | ||
</note> | </note> | ||
- | En los temas anteriores hemos visto como añadir las validaciones y como saber desde JavaScript las validaciones que han fallado. Ahora toca la parte de mostrar al usuario los mensajes de error. | + | 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. |
Línea 19: | Línea 19: | ||
<span ng-show="miFormulario.nombre.$error.maxlength">El tamaño máximo debe ser 50</span> | <span ng-show="miFormulario.nombre.$error.maxlength">El tamaño máximo debe ser 50</span> | ||
</sxh> | </sxh> | ||
- | * Línea 2: El mensaje solo se mostrará si ''miFormulario.nombre.$error.maxlength==true'' y eso solo ocurre si realmente el valor tiene un tamaño mayor que 50. | + | * 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á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á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}} |