1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
|
---
title: Validación de formularios de datos
slug: Learn/Forms/Form_validation
tags:
- Ejemplo
- Guía
- HTML
- Intermedio
- JavaScript
- Web
- formulários
translation_of: Learn/Forms/Form_validation
original_slug: Learn/HTML/Forms/Validacion_formulario_datos
---
<div>{{LearnSidebar}}</div>
<div>{{PreviousMenuNext("Learn/Forms/UI_pseudo-classes", "Learn/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}</div>
<p>Antes de enviar datos al servidor, es importante asegurarse de que se completan todos los controles de formulario requeridos, y en el formato correcto. Esto se denomina <strong>validación de formulario en el lado del cliente</strong> y ayuda a garantizar que los datos que se envían coinciden con los requisitos establecidos en los diversos controles de formulario. Este artículo te guiará por los conceptos básicos y ejemplos de validación de formularios en el lado del cliente.</p>
<table class="learn-box standard-table">
<tbody>
<tr>
<th scope="row">Prerrequisitos:</th>
<td>Conocimientos básicos de informática, y entender cómo funcionan el <a href="/es/docs/Learn/HTML">HTML</a>, el <a href="/es/docs/Learn/CSS">CSS</a> y el <a href="/es/docs/Learn/JavaScript">JavaScript</a>.</td>
</tr>
<tr>
<th scope="row">Objetivo:</th>
<td>Entender qué es la validación de formularios en el lado del cliente, porqué es importante y cómo aplicar diversas técnicas para implementarla.</td>
</tr>
</tbody>
</table>
<p>La validación en el lado del cliente es una verificación inicial y una característica importante para garantizar una buena experiencia de usuario; mediante la detección de datos no válidos en el lado del cliente, el usuario puede corregirlos de inmediato. Si el servidor lo recibe y, a continuación, lo rechaza; se produce un retraso considerable en la comunicación entre el servidor y el cliente que insta al usuario a corregir sus datos.</p>
<p>Sin embargo, ¡la validación en el lado del cliente <em>no debe considerarse </em> una medida de seguridad exhaustiva! Tus aplicaciones siempre deben realizar comprobaciones de seguridad de los datos enviados por el formulario <em>en el lado del servidor</em>, <strong>así como también</strong> en el lado del cliente, porque la validación en el lado del cliente es demasiado fácil de evitar, por lo que los usuarios malintencionados pueden enviar fácilmente datos incorrectos a tu servidor. Lee <a href="/es/docs/Learn/Server-side/Primeros_pasos/seguridad_sitios_web">Seguridad en los sitios web</a> para ver qué <em>podría</em> suceder. Cómo implementar la validación en el lado del servidor está fuera del alcance de este módulo, pero debes tenerlo en cuenta.</p>
<h2 id="¿Qué_es_la_validación_de_formularios">¿Qué es la validación de formularios?</h2>
<p>Ve a cualquier sitio web popular que incluya un formulario de registro y observa que proporcionan comentarios cuando no introduces tus datos en el formato que se espera. Recibirás mensajes como:</p>
<ul>
<li>«Este campo es obligatorio» (No se puede dejar este campo en blanco).</li>
<li>«Introduzca su número de teléfono en el formato xxx-xxxx» (Se requiere un formato de datos específico para que se considere válido).</li>
<li>«Introduzca una dirección de correo electrónico válida» (los datos que introdujiste no están en el formato correcto).</li>
<li>«Su contraseña debe tener entre 8 y 30 caracteres y contener una letra mayúscula, un símbolo y un número». (Se requiere un formato de datos muy específico para tus datos).</li>
</ul>
<p>Esto se llama <strong>validación de formulario</strong>. Cuando introduces los datos, el navegador y/o el servidor web verifican que estén en el formato correcto y dentro de las restricciones establecidas por la aplicación. La validación realizada en el navegador se denomina validación <strong>en el lado del cliente</strong>, mientras que la validación realizada en el servidor se denomina validación <strong>en el lado del servidor</strong>. En este capítulo nos centraremos en la validación en el lado del cliente.</p>
<p>Si la información está en el formato correcto, la aplicación permite que los datos se envíen al servidor y (en general) que se guarden en una base de datos; si la información no está en el formato correcto, da al usuario un mensaje de error que explica lo que debe corregir y le permite volver a intentarlo.</p>
<p>Queremos que completar formularios web sea lo más fácil posible. Entonces, ¿por qué insistimos en validar nuestros formularios? Hay tres razones principales:</p>
<ul>
<li><strong>Queremos obtener los datos correctos en el formato correcto.</strong> Nuestras aplicaciones no funcionarán correctamente si los datos de nuestros usuarios se almacenan en el formato incorrecto, son incorrectos o se omiten por completo.</li>
<li><strong>Queremos proteger los datos de nuestros usuarios</strong>. Obligar a nuestros usuarios a introducir contraseñas seguras facilita proteger la información de su cuenta.</li>
<li><strong>Queremos protegernos a nosotros mismo</strong>. Hay muchas formas en que los usuarios maliciosos puedan usar mal los formularios desprotegidos y dañar la aplicación (consulta <a href="/es/docs/Learn/Server-side/Primeros_pasos/seguridad_sitios_web">Seguridad del sitio web</a>).</li>
</ul>
<div class="warning"><strong>Atención:</strong> No confíes nunca en los datos que se pasan al servidor desde el cliente. Incluso si tu formulario se valida correctamente y evita la introducción de datos con formato incorrecto en el lado del cliente, un usuario malintencionado puede alterar la petición de red.</div>
<h2 id="Diferentes_tipos_de_validación_en_el_lado_del_cliente">Diferentes tipos de validación en el lado del cliente</h2>
<p>Hay dos tipos diferentes de validación por parte del cliente que encontrarás en la web:</p>
<ul>
<li>La <strong>validación de formularios incorporada</strong> utiliza características de validación de formularios HTML5, que hemos visto en muchos lugares a lo largo de este módulo. Esta validación generalmente no requiere mucho JavaScript. La validación de formularios incorporada tiene un mejor rendimiento que JavaScript, pero no es tan personalizable como la validación con JavaScript.</li>
<li>La <strong>validación con JavaScript</strong> se codifica utilizando JavaScript. Esta validación es completamente personalizable, pero debes crearlo todo (o usar una biblioteca).</li>
</ul>
<h2 id="Usar_la_validación_de_formulario_incorporada">Usar la validación de formulario incorporada</h2>
<p>Una de las características más importantes de los <a href="/en-US/docs/Learn/Forms/HTML5_input_types">controles de formulario de HTML5</a> es la capacidad de validar la mayoría de los datos de usuario sin depender de JavaScript. Esto se realiza mediante el uso de atributos de validación en los elementos del formulario. Los hemos visto anteriormente en el curso, pero recapitulamos aquí:</p>
<ul>
<li><code><a href="/en-US/docs/Web/HTML/Attributes/required">required</a></code>: Especifica si un campo de formulario debe completarse antes de que se pueda enviar el formulario.</li>
<li><code><a href="/en-US/docs/Web/HTML/Attributes/minlength">minlength</a></code> y <code><a href="/en-US/docs/Web/HTML/Attributes/maxlength">maxlength</a></code>: Especifican la longitud mínima y máxima de los datos de texto (cadenas).</li>
<li><code><a href="/en-US/docs/Web/HTML/Attributes/min">min</a></code> y <code><a href="/en-US/docs/Web/HTML/Attributes/max">max</a></code>: Especifican los valores mínimo y máximo de los tipos de entrada numéricos.</li>
<li><code>type</code>: Especifica si los datos deben ser un número, una dirección de correo electrónico o algún otro tipo de preajuste específico. </li>
<li><code><a href="/en-US/docs/Web/HTML/Attributes/pattern">pattern</a></code>: Especifica una <a href="/es/docs/Web/JavaScript/Guide/Regular_Expressions">expresión regular</a> que define un patrón que los datos que se introduzcan deben seguir.</li>
</ul>
<p>Si los datos que se introducen en un campo de formulario siguen todas las reglas que especifican los atributos anteriores, se consideran válidos. Si no, se consideran no válidos.</p>
<p>Cuando un elemento es válido, se cumplen los aspectos siguientes:</p>
<ul>
<li>El elemento coincide con la pseudoclase {{cssxref(":valid")}} de CSS, lo que te permite aplicar un estilo específico a los elementos válidos.</li>
<li>Si el usuario intenta enviar los datos, el navegador envía el formulario siempre que no haya nada más que lo impida (por ejemplo, JavaScript).</li>
</ul>
<p>Cuando un elemento no es válido, se cumplen los aspectos siguientes:</p>
<ul>
<li>El elemento coincide con la pseudoclase {{cssxref(":invalid")}} de CSS, y a veces con otras pseudoclases de interfaz de usuario (UI) –por ejemplo, {{cssxref(":out-of-range")}}– dependiendo del error, que te permite aplicar un estilo específico a elementos no válidos.</li>
<li>Si el usuario intenta enviar los datos, el navegador bloquea el formulario y muestra un mensaje de error.</li>
</ul>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Hay varios errores que evitan que el formulario se envíe, incluidos {{domxref('validityState.badInput', 'badInput')}}, {{domxref('validityState.patternMismatch','patternMismatch')}}, {{domxref('validityState.rangeOverflow','rangeOverflow')}} o {{domxref('validityState.rangeUnderflow','rangeUnderflow')}}, {{domxref('validityState.stepMismatch','stepMismatch')}}, {{domxref('validityState.tooLong','tooLong')}} o {{domxref('validityState.tooShort','tooShort')}}, {{domxref('validityState.typeMismatch','typeMismatch')}}, {{domxref('validityState.valueMissing','valueMissing')}} o {{domxref('validityState.customError','customError')}}.</p>
</div>
<h2 id="Ejemplos_de_validación_de_formularios_incorporados">Ejemplos de validación de formularios incorporados</h2>
<p>En esta sección probaremos algunos de los atributos que hemos comentado antes.</p>
<h3 id="Archivo_de_inicio_sencillo">Archivo de inicio sencillo</h3>
<p>Vamos a empezar con un ejemplo sencillo: una entrada que te permite elegir si prefieres un plátano o una cereza. Este ejemplo implica una simple entrada ({{HTMLElement("input")}}) de texto con una etiqueta ({{htmlelement("label")}}) asociada y un botón de envío ({{htmlelement ("button")}}). Puedes encontrar el código fuente en GitHub en <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a> y el ejemplo en vivo a continuación.</p>
<pre class="brush: html notranslate"><form>
<label for="choose">¿Prefieres un plátano o una cereza?</label>
<input id="choose" name="i_like">
<button>Enviar</button>
</form></pre>
<pre class="brush: css notranslate">input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}</pre>
<p>{{EmbedLiveSample("Archivo_de_inicio_sencillo", "100%", 80)}}</p>
<p>Para empezar, haz una copia de <code>fruit-start.html</code> en un nuevo directorio de tu disco duro.</p>
<h3 id="El_atributo_required">El atributo <code>required</code></h3>
<p>La característica de validación de HTML5 más simple es el atributo <code><a href="/en-US/docs/Web/HTML/Attributes/required">required</a></code>. Añade este atributo al elemento para que una entrada sea obligatoria. Cuando se establece este atributo, el elemento coincide con la pseudoclase de la interfaz de usuario {{cssxref(':required')}} y el formulario no se envía; muestra un mensaje de error al enviarlo si la entrada está vacía. Si está vacía, la entrada también se considera inválida, coincidiendo con la pseudoclase de interfaz de usuario {{cssxref(':invalid')}}.</p>
<p>Añade un atributo <code>required</code> a tu entrada, como se muestra a continuación.</p>
<pre class="brush: html notranslate"><form>
<label for="choose">¿Prefieres un plátano o una cereza? (requerido) </label>
<input id="choose" name="i_like" <strong>required</strong>>
<button>Enviar</button>
</form></pre>
<p>Ten en cuenta el CSS que en el archivo de ejemplo se ha incluido:</p>
<pre class="brush: css notranslate">input:invalid {
border: 2px dashed red;
}
input:invalid:required {
background-image: linear-gradient(to right, pink, lightgreen);
}
input:valid {
border: 2px solid black;
}</pre>
<p>Este CSS da un borde discontinuo rojo cuando la entrada no es válida, y un borde negro sólido más sutil cuando es válida. También añadimos un gradiente de fondo cuando la entrada es obligatoria <em>y</em> no válida. Prueba el nuevo comportamiento en el ejemplo siguiente:</p>
<p>{{EmbedLiveSample("El_atributo_required", "100%", 80)}}</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Puedes encontrar este ejemplo en vivo en GitHub como <a href="https://mdn.github.io/learning-area/html/forms/form-validation/fruit-required.html">fruit-validation.html</a> (consulta también el <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-required.html">código fuente</a>).</p>
</div>
<p>Intenta enviar el formulario sin introducir ningún valor. Observa que la entrada no válida recibe el cursor, aparece un mensaje de error predeterminado («Complete este campo») y el formulario no se puede enviar.</p>
<p>La presencia del atributo <code>required</code> en cualquier elemento que admite este atributo significa que el elemento coincide con la pseudoclase {{cssxref(':required')}}, tenga o no un valor. Si en el elemento {{HTMLElement("input")}} no se ha introducido ningún valor, <code>input</code> coincidirá con la pseudoclase {{cssxref(':invalid')}}.</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Para una buena experiencia de usuario, indica al usuario que campos de formulario se requieren. No solo es una buena experiencia de usuario, sino que lo exigen las pautas de <a href="/es/docs/Learn/Accessibility">accesibilidad</a> de WCAG. Además, solo requiere que los usuarios introduzcan los datos que realmente necesitas: Por ejemplo, ¿por qué realmente necesitas saber el género o el tratamiento de alguien?</p>
</div>
<h3 id="Validación_de_una_expresión_regular">Validación de una expresión regular</h3>
<p>Otra característica útil de validación es el atributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a>, que espera una <a href="/es/docs/Web/JavaScript/Guide/Regular_Expressions">expresión regular</a> como valor. Una expresión regular (<em>regex</em>) es un patrón que se puede usar para establecer combinaciones de caracteres en cadenas de texto, por lo que las expresiones regulares son ideales para la validación de formularios y sirven para una gran variedad de otros usos en JavaScript.</p>
<p>Las expresiones regulares son bastante complejas y no vamos a exponerlas exhaustivamente en este artículo. A continuación hay algunos ejemplos para que te hagas una idea de cómo funcionan.</p>
<ul>
<li><code>a</code>: coincide con un carácter que es <code>a</code> (ni <code>b</code>, ni <code>aa</code>, etc.).</li>
<li><code>abc</code>: coincide con <code>a</code>, seguido de <code>b</code>, seguido de <code>c</code>.</li>
<li><code>ab?c</code>: coincide con <code>a</code>, seguida opcionalmente de una sola <code>b</code>, seguida de <code>c</code> (<code>ac</code> o <code>abc</code>).</li>
<li><code>ab*c</code>: coincide con <code>a</code>, seguido opcionalmente de cualquier número de <code>b</code>, seguido de <code>c</code>. (<code>ac</code>, <code>abc</code>, <code>abbbbbc</code>, etc.)</li>
<li><code>a|b</code>: coincide con un carácter que es <code>a</code> o <code>b</code>.</li>
<li><code>abc|xyz</code>: coincide exactamente con <code>abc</code> o <code>xyz</code> (pero no con <code>abcxyz</code> <code>a</code> o <code>y</code>, y así sucesivamente).</li>
</ul>
<p>Hay muchas más posibilidades que no exponemos aquí. Para obtener una lista completa y muchos ejemplos, consulta nuestro documento de <a href="/es/docs/Web/JavaScript/Guide/Regular_Expressions">expresiones regulares</a>.</p>
<p>Implementemos un ejemplo. Actualiza tu HTML para añadir un atributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a> como este:</p>
<pre class="brush: html notranslate"><form>
<label for="choose">¿Prefieres un plátano o una cereza?</label>
<input id="choose" name="i_like" required pattern="[Pp]látano|[Cc]ereza ">
<button>Enviar</button>
</form>
</pre>
<div class="hidden">
<pre class="brush: css notranslate">input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}</pre>
</div>
<p>Esto nos da la siguiente actualización; pruébalo:</p>
<p>{{EmbedLiveSample("Validación de una expresión regular", "100%", 80)}}</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Puedes encontrar este ejemplo en vivo en GitHub como <a href="https://mdn.github.io/learning-area/html/forms/form-validation/fruit-pattern.html">fruit-pattern.html</a> (consulta también su <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-pattern.html">código fuente</a>).</p>
</div>
<p>En este ejemplo, el elemento {{HTMLElement("input")}} acepta uno de los cuatro valores posibles: las cadenas «plátano», «Plátano», «cereza» o «Cereza». Las expresiones regulares distinguen entre mayúsculas y minúsculas, pero hemos hecho que admita versiones en mayúsculas y minúsculas utilizando un patrón «Aa» adicional anidado dentro de corchetes.</p>
<p>En este punto, intenta cambiar el valor dentro del atributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a> para que se vean iguales que algunos de los ejemplos vistos anteriormente, y observa que esto afecta a los valores que puedes añadir para que el valor de entrada sea válido. Intenta escribir algo por tu cuenta y mira cómo va. ¡Haz que estén relacionadas con la fruta siempre que sea posible para que tus ejemplos tengan sentido!</p>
<p>Si un valor no vacío de {{HTMLElement("input")}} no coincide con el patrón de la expresión regular, <code>input</code> coincidirá con la pseudoclase {{cssxref(':invalid')}}.</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Algunos tipos de elementos {{HTMLElement ("input")}} no necesitan validar una expresión regular con el atributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a>. Especificar el tipo de correo electrónico (<code>email</code>), por ejemplo, valida el valor de las entradas con un patrón de dirección de correo electrónico bien formado o un patrón que coincida con una lista de direcciones de correo electrónico separadas por comas si tiene el atributo <a href="/en-US/docs/Web/HTML/Attributes/multiple"><code>multiple</code></a>.</p>
</div>
<div class="blockIndicator note">
<p><strong>Nota</strong>: El elemento {{HTMLElement("textarea")}} no admite el atributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a>.</p>
</div>
<h3 id="Restringir_la_longitud_de_tus_entradas">Restringir la longitud de tus entradas</h3>
<p>Puedes restringir la longitud de los caracteres de todos los campos de texto creados por {{HTMLElement("input")}} o {{HTMLElement("textarea")}} utilizando los atributos <a href="/en-US/docs/Web/HTML/Attributes/minlength"><code>minlength</code></a> y <code><a href="/en-US/docs/Web/HTML/Attributes/maxlength">maxlength</a></code>. Un campo no es válido si tiene un valor y ese valor tiene menos caracteres que el valor de longitud mínima (<a href="/en-US/docs/Web/HTML/Attributes/minlength"><code>minlength</code></a>), o más que el valor de longitud máxima (<code><a href="/en-US/docs/Web/HTML/Attributes/maxlength">maxlength</a></code>).</p>
<p>Los navegadores a menudo no permiten que el usuario escriba un valor más largo de lo esperado en los campos de texto. Lo que otorga una mejor experiencia de usuario que <code>maxlength</code> es proporcionar comentarios de recuento de caracteres de manera accesible y permitirles editar su contenido a un tamaño más reducido. Un ejemplo de esto es el límite de caracteres de Twitter. JavaScript, incluidas las <a href="https://github.com/mimo84/bootstrap-maxlength">soluciones que utilizan <code>maxlength</code></a>, se puede utilizar para proporcionar esta funcionalidad.</p>
<h3 id="Restringir_los_valores_de_tus_entradas">Restringir los valores de tus entradas</h3>
<p>Los atributos <code><a href="/en-US/docs/Web/HTML/Attributes/min">min</a></code> y <code><a href="/en-US/docs/Web/HTML/Attributes/max">max</a></code> se pueden usar para proporcionar a los campos numéricos (es decir, <code><a href="/en-US/docs/Web/HTML/Element/input/number"><input type="number"></a></code>) un rango de valores válidos. El campo no será válido si contiene un valor fuera de este rango.</p>
<p>Veamos otro ejemplo. Crea una nueva copia del archivo <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a>.</p>
<p>Ahora elimina el contenido del elemento <code><body></code> y reemplázalo con lo siguiente:</p>
<pre class="brush: html notranslate"><form>
<div>
<label for="choose">¿Prefieres un plátano o una cereza?</label>
<input type="text" id="choose" name="i_like" required minlength="6" maxlength="6">
</div>
<div>
<label for="number">¿Cuántos te gustaría comer?</label>
<input type="number" id="number" name="amount" value="1" min="1" max="10">
</div>
<div>
<button>Enviar</button>
</div>
</form></pre>
<ul>
<li>Aquí verás que le hemos dado al campo de <code>text</code> unos valores <code>minlength</code> y <code>maxlength</code> de seis, que es la misma longitud que tienen el plátano y la cereza.</li>
<li>También le hemos dado al campo <code>number</code> un <code>min</code> de uno y un <code>max</code> de diez. Los números introducidos que queden fuera de este rango se mostrarán como no válidos; los usuarios no podrán usar las flechas de incremento/decremento para mover el valor fuera de este rango. Si el usuario introduce un número desde el teclado fuera de este rango, los datos no serán válidos. El número no es obligatorio, por lo que eliminar el valor aún dará como resultado un valor válido.</li>
</ul>
<div class="hidden">
<pre class="brush: css notranslate">input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}
div {
margin-bottom: 10px;
}</pre>
</div>
<p>Aquí está el ejemplo que se ejecuta en vivo:</p>
<p>{{EmbedLiveSample("Restringir_los_valores_de_tus_entradas", "100%", 100)}}</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Puedes encontrar este ejemplo en vivo en GitHub como <a href="https://mdn.github.io/learning-area/html/forms/form-validation/fruit-length.html">fruit-length.html</a> (consulta también su <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-length.html">código fuente</a>).</p>
</div>
<div class="blockIndicator note">
<p><strong>Nota</strong>: <code><input type="number"></code> (y otros tipos, como <code>range</code> y <code>date</code>) también pueden tomar un atributo <a href="/en-US/docs/Web/HTML/Attributes/step"><code>step</code></a>, que especifica en qué incremento aumenta o disminuye el valor cuando se utilizan los controles de entrada (como el botones numéricos arriba y abajo). En el ejemplo anterior no hemos incluido un atributo <code>step</code>, por lo que el valor predeterminado es <code>1</code>. Esto significa que los valores de coma flotante, como 3.2, también se mostrarán como no válidos.</p>
</div>
<h3 id="Ejemplo_completo">Ejemplo completo</h3>
<p>Aquí hay un ejemplo completo que muestra el uso de las funciones de validación integradas en HTML. En primer lugar, un poco de HTML:</p>
<pre class="brush: html notranslate"><form>
<p>
<fieldset>
<legend>¿Tienes carné de conducir?<abbr title="Este campo es obligatorio" aria-label="required">*</abbr></legend>
<!-- Solo se puede seleccionar un botón de opción en un grupo con el mismo nombre,
y, por lo tanto, solo un botón de opción en un grupo con el mismo nombre que tiene marcado el atributo «requerido»
basta para hacer de una selección un requisito -->
<input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Sí</label>
<input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label>
</fieldset>
</p>
<p>
<label for="n1">¿Qué edad tienes?</label>
<!-- El atributo pattern puede actuar como una alternativa para los navegadores que
no implementan el tipo de entrada de número, pero admiten el atributo pattern.
Ten en cuenta que los navegadores que admiten el atributo pattern lo harán
fallar silenciosamente cuando se use con un campo numérico.
Su uso aquí solo actúa como una alternativa -->
<input type="number" min="12" max="120" step="1" id="n1" name="age"
pattern="\d+">
</p>
<p>
<label for="t1">¿Cuál es tu fruta favorita?<abbr title="Este campo es obligatorio" aria-label="required">*</abbr></label>
<input type="text" id="t1" name="fruit" list="l1" required
pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range ">
<datalist id="l1">
<option>Plátano</option>
<option>Cereza</option>
<option>Manzana</option>
<option>Fresa</option>
<option>Limón</option>
<option>Naranja</option>
</datalist>
</p>
<p>
<label for="t2">¿Cuál es tu dirección de correo electrónico? </label>
<input type="email" id="t2" name="email">
</p>
<p>
<label for="t3">Deja un mensaje</label>
<textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
</p>
<p>
<button>Enviar</button>
</p>
</form></pre>
<p>Y ahora, algo de CSS para añadir estilo al HTML:</p>
<pre class="brush: css notranslate">form {
font: 1em sans-serif;
max-width: 320px;
}
p > label {
display: block;
}
input[type="text"],
input[type="email"],
input[type="number"],
textarea,
fieldset {
width : 100%;
border: 1px solid #333;
box-sizing: border-box;
}
input:invalid {
box-shadow: 0 0 5px 1px red;
}
input:focus:invalid {
box-shadow: none;
}</pre>
<p>Esto se traduce de la siguiente manera:</p>
<p>{{EmbedLiveSample("Ejemplo_completo", "100%", 420)}}</p>
<p>Consulta <a href="/es/docs/HTML/HTML5/Validacion_de_restricciones#Atributos_relacionados_con_validaciones">Atributos relacionados con la validación</a> para obtener una lista completa de los atributos que se pueden usar para restringir los valores de entrada y los tipos de entrada que los admiten.</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Puedes encontrar este ejemplo en vivo en GitHub como <a href="https://mdn.github.io/learning-area/html/forms/form-validation/full-example.html">full-example.html</a> (consulta también su <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/full-example.html">código fuente</a>).</p>
</div>
<h2 id="Validar_formularios_utilizando_JavaScript">Validar formularios utilizando JavaScript</h2>
<p>Debes usar JavaScript si quieres controlar la apariencia de los mensajes de error nativos o tratar con navegadores heredados que no admiten la validación de formularios incorporados en HTML. En esta sección veremos las diferentes formas de hacer esto.</p>
<h3 id="La_API_de_validación_de_restricciones">La API de validación de restricciones</h3>
<p>La mayoría de los navegadores admiten la <a href="/en-US/docs/Web/API/Constraint_validation">API de validación de restricciones</a>, que consta de un conjunto de métodos y propiedades disponibles en las interfaces DOM de elementos de formulario siguientes:</p>
<ul>
<li><code><a href="/en-US/docs/Web/API/HTMLButtonElement">HTMLButtonElement</a></code> (representa un elemento <code><a href="/en-US/docs/Web/HTML/Element/button"><button></a></code>)</li>
<li><code><a href="/en-US/docs/Web/API/HTMLFieldSetElement">HTMLFieldSetElement</a></code> (representa un elemento <code><a href="/en-US/docs/Web/HTML/Element/fieldset"><fieldset></a></code>)</li>
<li><code><a href="/en-US/docs/Web/API/HTMLInputElement">HTMLInputElement</a></code> (representa un elemento <code><a href="/en-US/docs/Web/HTML/Element/input"><input></a></code>)</li>
<li><code><a href="/en-US/docs/Web/API/HTMLOutputElement">HTMLOutputElement</a></code> (representa un elemento <code><a href="/en-US/docs/Web/HTML/Element/output"><output></a></code>)</li>
<li><code><a href="/en-US/docs/Web/API/HTMLSelectElement">HTMLSelectElement</a></code> (representa un elemento <code><a href="/en-US/docs/Web/HTML/Element/select"><select></a></code>)</li>
<li><code><a href="/en-US/docs/Web/API/HTMLTextAreaElement">HTMLTextAreaElement</a></code> (representa un elemento <code><a href="/en-US/docs/Web/HTML/Element/textarea"><textarea></a></code>)</li>
</ul>
<p id="Constraint_validation_API_properties">La API de validación de restricciones hace que las propiedades siguientes estén disponibles en los elementos anteriores.</p>
<ul>
<li><code>validationMessage</code>: Devuelve un mensaje localizado que describe las restricciones de validación que el control no satisface (si corresponde). Si el control no es candidato para la validación de restricciones (<code>willValidate</code> es <code>false</code>) o el valor del elemento satisface sus restricciones (es válido), esto devolverá una cadena vacía.</li>
<li><code>validity</code>: Devuelve un objeto <code>ValidityState</code> que contiene varias propiedades que describen el estado de validez del elemento. Puedes encontrar todos los detalles de todas las propiedades disponibles en la página de referencia {{domxref("ValidityState")}}; a continuación se enumeran algunos de los más comunes:
<ul>
<li>{{domxref("ValidityState.patternMismatch", "patternMismatch")}}: Devuelve <code>true</code> si el valor no coincide con el {{htmlattrxref("pattern", "input")}} especificado, y <code>false</code> si coincide. Si es verdadero, el elemento coincide con la pseudoclase {{cssxref(":invalid")}} de CSS.</li>
<li>{{domxref("ValidityState.tooLong", "tooLong")}}: Devuelve <code>true</code> si el valor es mayor que la longitud máxima especificada por el atributo {{htmlattrxref("maxlength", "input")}}, o <code>false</code> si es menor o igual al máximo. Si es verdadero, el elemento coincide con la pseudoclase {{cssxref(":invalid")}} de CSS.</li>
<li>{{domxref("ValidityState.tooShort", "tooShort")}}: Devuelve <code>true</code> si el valor es menor que la longitud mínima especificada por el atributo {{htmlattrxref("minlength", "input")}}, o <code>false</code> si es mayor o igual al mínmo. Si es verdadero, el elemento coincide con la pseudoclase {{cssxref(":invalid")}} de CSS.</li>
<li>{{domxref("ValidityState.rangeOverflow", "rangeOverflow")}}: Devuelve <code>true</code> si el valor es mayor que el máximo especificado por el atributo {{htmlattrxref("max", "input")}}, o <code>false</code> si es menor o igual que el máximo. Si es verdadero, el elemento coincide con las pseudoclases {{cssxref(":invalid")}} y {{cssxref(":out-of-range")}} de CSS.</li>
<li>{{domxref("ValidityState.rangeUnderflow", "rangeUnderflow")}}: Devuelve <code>true</code> si el valor es menor que el mínimo especificado por el atributo {{htmlattrxref("min", "input")}}, o <code>false</code> si es mayor o igual que el mínimo. Si es verdadero, el elemento coincide con las pseudoclases {{cssxref(":invalid")}} y {{cssxref(":out-of-range")}} de CSS.</li>
<li>{{domxref("ValidityState.typeMismatch", "typeMismatch")}}: Devuelve <code>true</code> si el valor no está en la sintaxis requerida (cuando {{htmlattrxref("type", "input")}} es <code>email</code> o <code>url</code>), o <code>false</code> si la sintaxis es correcta. Si es verdadero, el elemento coincide con la pseudoclase {{cssxref(":invalid")}} de CSS.</li>
<li><code>valid</code>: Devuelve <code>true</code> si el elemento cumple con todas sus restricciones de validación y por lo tanto se considera válido, o <code>false</code> si falla alguna restricción. Si es verdadero, el elemento coincide con la pseudoclase {{cssxref(":valid")}} de CSS; o con la pseudoclase {{cssxref(":invalid")}} de CSS de lo contrario.</li>
<li><code>valueMissing</code>: Devuelve <code>true</code> si el elemento tiene un atributo {{htmlattrxref("required", "input")}} pero no tiene valor, o <code>false</code> de lo contrario. Si es verdadero, el elemento coincide con la pseudoclase {{cssxref(":invalid")}} de CSS.</li>
</ul>
</li>
<li><code>willValidate</code>: Devuelve <code>true</code> si el elemento se valida cuando se envía el formulario; <code>false</code> de lo contrario.</li>
</ul>
<p id="Constraint_validation_API_methods">La API de validación de restricciones también pone a disposición los siguientes métodos en los elementos anteriores.</p>
<ul>
<li><code>checkValidity()</code>: Devuelve <code>true</code> si el valor del elemento no tiene problemas de validez; <code>false</code> en caso contrario. Si el elemento no es válido, este método también activa un <a href="/es/docs/Web/API/HTMLInputElement/invalid_event">evento <code>invalid</code></a> en el elemento.</li>
<li><code>setCustomValidity(<em>message</em>)</code>: Añade un mensaje de error personalizado al elemento; si configuras un mensaje de error personalizado, el elemento se considera no válido y se muestra el error especificado. Esto te permite utilizar el código JavaScript para establecer un fallo de validación distinto de los ofrecidos por las restricciones estándar de validación de HTML5. El mensaje se muestra al usuario cuando se informa del problema.</li>
</ul>
<h4 id="Implementar_un_mensaje_de_error_personalizado">Implementar un mensaje de error personalizado</h4>
<p>Como has visto en los ejemplos de restricciones de validación de HTML5 anteriores, cada vez que un usuario intenta enviar un formulario no válido, el navegador muestra un mensaje de error. La forma en que se muestra este mensaje depende del navegador.</p>
<p>Estos mensajes automatizados tienen dos inconvenientes:</p>
<ul>
<li>No hay una forma estándar de cambiar su aspecto con CSS.</li>
<li>Dependen de la configuración regional del navegador, lo que significa que puedes tener una página en un idioma pero un mensaje de error en otro idioma, como se ve en la siguiente captura de pantalla de Firefox.</li>
</ul>
<p><img alt="Ejemplo de un mensaje de error en francés en una página de Firefox en inglés" src="/files/4329/error-firefox-win7.png" style="height: 97px; width: 228px;"></p>
<p>La personalización de estos mensajes de error es uno de los casos de uso más comunes de la <a href="/en-US/docs/Web/API/Constraint_validation" rel="external">API de validación de restricciones</a>. Veamos un ejemplo simple de cómo hacer esto.</p>
<p>Comenzaremos con un HTML simple (siéntete libre de poner esto en un archivo HTML en blanco; usa una copia nueva de <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a> como base, si lo deseas):</p>
<pre class="brush: html notranslate"><form>
<label for="mail">Me gustaría que me proporcionara una dirección de correo electrónico:<label>
<input type="email" id="mail" name="mail">
<button>Enviar</button>
</form></pre>
<p>Y añade a la página el JavaScript siguiente:</p>
<pre class="brush: js notranslate">const email = document.getElementById("mail");
email.addEventListener("input", function (event) {
if (email.validity.typeMismatch) {
email.setCustomValidity("¡Se esperaba una dirección de correo electrónico!");
} else {
email.setCustomValidity("");
}
});</pre>
<p>Aquí guardamos una referencia para la entrada de la dirección de correo electrónico, luego le añadimos un detector de eventos que ejecuta el código de <code>content</code> cada vez que el valor de la entrada cambia.</p>
<p>Dentro del código que contiene, verificamos si la propiedad <code>validity.typeMismatch</code> de la entrada de la dirección de correo electrónico devuelve <code>true</code>, lo que significa que el valor que contiene no coincide con el patrón para una dirección de correo electrónico bien formada. Si es así, llamamos al método <a href="/es/docs/HTML/HTML5/Validacion_de_restricciones"><code>setCustomValidity()</code></a> con un mensaje personalizado. Esto hace que la entrada no sea válida, de modo que cuando intentas enviar el formulario, el envío falla y se muestra el mensaje de error personalizado.</p>
<p>Si la propiedad <code>validity.typeMismatch</code> devuelve <code>false</code>, llamamos al método <code>setCustomValidity()</code> con una cadena vacía. Esto hace que la entrada sea válida, y el formulario se envía.</p>
<p>Puedes probarlo a continuación:</p>
<p>{{EmbedGHLiveSample("/en-US/learning-area/html/forms/form-validation/custom-error-message.html", '100%', 80)}}</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Puede encontrar este ejemplo vivo en GitHub como <a href="https://mdn.github.io/learning-area/html/forms/form-validation/custom-error-message.html">custom-error-message.html</a> (véase también su <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/custom-error-message.html">código fuente</a>).</p>
</div>
<h4 id="Un_ejemplo_más_detallado">Un ejemplo más detallado</h4>
<p>Ahora que hemos visto un ejemplo realmente sencillo, veamos cómo podemos usar esta API para construir una validación personalizada un poco más compleja.</p>
<p>En primer lugar, el código HTML. Una vez más, siéntete libre de construir esto junto con nosotros:</p>
<pre class="brush: html notranslate"><form novalidate>
<p>
<label for="mail">
<span>Por favor, introduzca una dirección de correo electrónico: </span>
<input type="email" id="mail" name="mail" required minlength="8">
<span class="error" aria-live="polite"></span>
</label>
</p>
<button>Enviar</button>
</form></pre>
<p>Este sencillo formulario usa el atributo <code><a href="/en-US/docs/Web/HTML/Attributes/novalidate">novalidate</a></code> para desactivar la validación automática del navegador; esto permite que nuestra secuencia de comandos tome control sobre la validación. Sin embargo, esto no deshabilita la compatibilidad para la API de validación de restricciones ni la aplicación de pseudoclases de CSS como {{cssxref(":valid")}}, etc. Eso significa que, aunque el navegador no verifica automáticamente la validez del formulario antes de enviar los datos, puedes hacerlo tú mismo y diseñar el formulario en consecuencia.</p>
<p>Nuestra entrada para validar es <code><a href="/es/docs/Web/HTML/Elemento/input/email"><input type="email"></a></code>, que es obligatoria y tiene una longitud mínima (<code>minlength</code>) de 8 caracteres. Vamos a verificar esto con nuestro propio código para que muestre un mensaje de error personalizado para cada elemento.</p>
<p>Nuestro objetivo es mostrar los mensajes de error dentro de un elemento <code><span></code>. El atributo <a href="/en-US/docs/Accessibility/ARIA/ARIA_Live_Regions"><code>aria-live</code></a> se establece en ese <code><span></code> para asegurar que todo el mundo podrá ver nuestro mensaje de error personalizado, incluidos los usuarios de lectores de pantalla.</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Un punto clave a tener en cuenta es que establecer el atributo <code>novalidate</code> en el formulario impide que el formulario muestre sus propios cuadros de diálogo de error, y nos permite mostrar los mensajes de error personalizados en el DOM de la manera que nosotros elijamos.</p>
</div>
<p>Ahora aplicaremos algo de CSS básico para mejorar ligeramente el aspecto del formulario y proporcionar algunos comentarios visuales cuando los datos de entrada no sean válidos:</p>
<pre class="brush: css notranslate">body {
font: 1em sans-serif;
width: 200px;
padding: 0;
margin : 0 auto;
}
p * {
display: block;
}
input[type=email]{
-webkit-appearance: none;
appearance: none;
width: 100%;
border: 1px solid #333;
margin: 0;
font-family: inherit;
font-size: 90%;
box-sizing: border-box;
}
/* Este es nuestro diseño para los campos no válidos */
input:invalid{
border-color: #900;
background-color: #FDD;
}
input:focus:invalid {
outline: none;
}
/* Este es el diseño para nuestros mensajes de error */
.error {
width : 100%;
padding: 0;
font-size: 80%;
color: white;
background-color: #900;
border-radius: 0 0 5px 5px;
box-sizing: border-box;
}
.error.active {
padding: 0.3em;
}</pre>
<p>Vamos a ver el JavaScript que implementa la validación de error personalizada.</p>
<pre class="brush: js notranslate">// Hay muchas formas de elegir un nodo DOM; aquí obtenemos el formulario y, a continuación, el campo de entrada
// del correo electrónico, así como el elemento span en el que colocaremos el mensaje de error.
const form = document.getElementsByTagName('form')[0];
const email = document.getElementById('mail');
const emailError = document.querySelector('#mail + span.error');
email.addEventListener('input', function (event) {
// Cada vez que el usuario escribe algo, verificamos si
// los campos del formulario son válidos.
if (email.validity.valid) {
// En caso de que haya un mensaje de error visible, si el campo
// es válido, eliminamos el mensaje de error.
emailError.innerHTML = ''; // Restablece el contenido del mensaje
emailError.className = 'error'; // Restablece el estado visual del mensaje
} else {
// Si todavía hay un error, muestra el error exacto
showError();
}
});
form.addEventListener('submit', function (event) {
// si el campo de correo electrónico es válido, dejamos que el formulario se envíe
if(!email.validity.valid) {
// Si no es así, mostramos un mensaje de error apropiado
showError();
// Luego evitamos que se envíe el formulario cancelando el evento
event.preventDefault();
}
});
function showError() {
if(email.validity.valueMissing) {
// Si el campo está vacío
// muestra el mensaje de error siguiente.
emailError.textContent = 'Debe introducir una dirección de correo electrónico.';
} else if(email.validity.typeMismatch) {
// Si el campo no contiene una dirección de correo electrónico
// muestra el mensaje de error siguiente.
emailError.textContent = 'El valor introducido debe ser una dirección de correo electrónico.';
} else if(email.validity.tooShort) {
// Si los datos son demasiado cortos
// muestra el mensaje de error siguiente.
emailError.textContent = 'El correo electrónico debe tener al menos ${ email.minLength } caracteres; ha introducido ${ email.value.length }.';
}
// Establece el estilo apropiado
emailError.className = 'error activo';
}</pre>
<p>Los comentarios explican las cosas bastante bien, pero de una manera muy breve:</p>
<ul>
<li>Cada vez que cambiamos el valor de la entrada, verificamos si contiene datos válidos. Si es así, eliminamos cualquier mensaje de error que se muestre. Si los datos no son válidos, ejecutamos <code>showError()</code> para mostrar el error correspondiente.</li>
<li>Cada vez que intentamos enviar el formulario, verificamos nuevamente si los datos son válidos. Si es así, dejamos que envíe el formulario. Si no, ejecutamos <code>showError()</code> para mostrar el error correspondiente y detenemos el envío del formulario con <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code>.</li>
<li>La función <code>showError()</code> usa varias propiedades de la entrada <code>validity</code> para determinar cuál es el error y luego muestra un mensaje de error según corresponda.</li>
</ul>
<p>Este es el resultado:</p>
<p>{{EmbedGHLiveSample("/en-US/learning-area/html/forms/form-validation/detailed-custom-validation.html", '100%', 150)}}</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Puedes encontrar este ejemplo en vivo en GitHub como <a href="https://mdn.github.io/learning-area/html/forms/form-validation/detailed-custom-validation.html">detailed-custom-validation.html</a> (consulta también su <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/detailed-custom-validation.html">código fuente</a>).</p>
</div>
<p>La API de validación de restricciones te proporciona una herramienta poderosa para manejar la validación de formularios, y te permite tener un control enorme sobre la interfaz de usuario más allá de lo que puedas hacer solo con HTML y CSS.</p>
<div class="blockIndicator note">
<p><strong>Nota</strong>: Para obtener más información, consulta nuestra <a href="/es/docs/HTML/HTML5/Validacion_de_restricciones">guía de validación de restricciones</a> y la referencia de <a href="/en-US/docs/Web/API/Constraint_validation">API de validación de restricciones</a>.</p>
</div>
<h3 id="Validar_formularios_sin_una_API_incorporada">Validar formularios sin una API incorporada</h3>
<p>En algunos casos, como la compatibilidad heredada del navegador o los <a href="/es/docs/Learn/HTML/Forms/como_crear_widgets_de_formularios_personalizados">controles personalizados</a>, no podrás o no querrás usar la API de validación de restricciones. Todavía puedes usar JavaScript para validar tu formulario, pero vas a tener que escribirlo.</p>
<p>Antes de validar el formulario, hazte estas preguntas:</p>
<dl>
<dt>¿Qué tipo de validación debería realizar?</dt>
<dd>Debes determinar cómo validar los datos: operaciones de cadena, conversión de tipos, expresiones regulares, etc. Tú decides.</dd>
<dt>¿Qué debo hacer si el formulario no se valida?</dt>
<dd>Esto es claramente un problema de la interfaz de usuario. Tienes que decidir cómo se comportará el formulario. ¿El formulario va a enviar los datos de todos modos? ¿Deberías resaltar los campos que dan error? ¿Deberías mostrar mensajes de error?</dd>
<dt>¿Cómo puedo ayudar al usuario a corregir datos no válidos?</dt>
<dd>Para reducir la frustración del usuario, es muy importante proporcionar tanta información útil como sea posible para guiarlo a fin de que corrija sus entradas de datos. Debes ofrecer sugerencias por adelantado para que sepan lo que se espera de ellos, así como mensajes de error claros. Si deseas profundizar en los requisitos de interfaz de usuario para la validación de formularios, aquí hay algunos artículos útiles que debes leer:
<ul>
<li>SmashingMagazine: <a href="http://uxdesign.smashingmagazine.com/2012/06/27/form-field-validation-errors-only-approach/" rel="external">Form-Field Validation: The Errors-Only Approach</a> [Validación de campo de formulario: El enfoque de solo errores]</li>
<li>SmashingMagazine: <a href="http://www.smashingmagazine.com/2009/07/07/web-form-validation-best-practices-and-tutorials/" rel="external">Web Form Validation: Best Practices and Tutorials </a> [Validación de formularios web: Buenas prácticas y tutoriales]</li>
<li>Six Revision: <a href="http://sixrevisions.com/user-interface/best-practices-for-hints-and-validation-in-web-forms/" rel="external">Best Practices for Hints and Validation in Web Forms</a> [Buenas prácticas para sugerencias y validación de formularios web]</li>
<li>A List Apart: <a href="http://www.alistapart.com/articles/inline-validation-in-web-forms/" rel="external">Inline Validation in Web Forms</a> [Validación en línea de formularios web]</li>
</ul>
</dd>
</dl>
<h4 id="Un_ejemplo_que_no_usa_la_API_de_validación_de_restricciones">Un ejemplo que no usa la API de validación de restricciones</h4>
<p>Para ilustrar esto, mostramos una versión simplificada del ejemplo anterior que funciona con navegadores con compatibilidad heredada.</p>
<p>El HTML es casi el mismo; solo hemos eliminado las funciones de validación de HTML.</p>
<pre class="brush: html notranslate"><form>
<p>
<label for="mail">
<span>Por favor, introduzca una dirección de correo electrónico: </span>
<input type="text" class="mail" id="mail" name="mail">
<span class="error" aria-live="polite"></span>
</label>
</p>
<!-- Algunos navegadores con compatibilidad heredada deben tener el atributo «type»
establecido explícitamente en el elemento «button» de «submit»-->
<button type="submit">Enviar</button>
</form></pre>
<p>Del mismo modo, no es necesario cambiar mucho el CSS; acabamos de convertir la pseudoclase {{cssxref(":invalid")}} de CSS en una clase real y evitamos usar el selector de atributos que no funciona en Internet Explorer 6.</p>
<pre class="brush: css notranslate">body {
font: 1em sans-serif;
width: 200px;
padding: 0;
margin : 0 auto;
}
form {
max-width: 200px;
}
p * {
display: block;
}
input.mail {
-webkit-appearance: none;
width: 100%;
border: 1px solid #333;
margin: 0;
font-family: inherit;
font-size: 90%;
box-sizing: border-box;
}
/* Este es nuestro diseño para los campos no válidos */
input.invalid{
border-color: #900;
background-color: #FDD;
}
input:focus.invalid {
outline: none;
}
/* Este es el diseño para nuestros mensajes de error */
.error {
width : 100%;
padding: 0;
font-size: 80%;
color: white;
background-color: #900;
border-radius: 0 0 5px 5px;
box-sizing: border-box;
}
.error.active {
padding: 0.3em;
}</pre>
<p>Los grandes cambios están en el código JavaScript, que necesita hacer mucho más trabajo pesado.</p>
<pre class="brush: js notranslate">// Hay menos formas de elegir un nodo DOM con navegadores antiguos
const form = document.getElementsByTagName('form')[0];
const email = document.getElementById('mail');
// Lo siguiente es un truco para llegar al siguiente nodo de elementos hermanos en el DOM
// Esto es peligroso porque puedes construir fácilmente un bucle infinito.
// En los navegadores modernos es mejor usar element.nextElementSibling
let error = email;
while ((error = error.nextSibling).nodeType != 1);
// según la especificación HTML5
const emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
// Muchos navegadores antiguos no son compatibles con el método addEventListener.
// Aquí hay una manera simple de manejar esto; está lejos de ser la única.
function addEvent(element, event, callback) {
let previousEventCallBack = element["on"+event];
element["on"+event] = function (e) {
const output = callback(e);
// Una devolución de llamada que devuelve «false» detiene la cadena de devolución de llamada
// e interrumpe la ejecución de la devolución de llamada del evento.
if (output === false) return false;
if (typeof previousEventCallBack === 'function') {
output = previousEventCallBack(e);
if(output === false) return false;
}
}
};
// Ahora podemos reconstruir nuestra restricción de validación
// Debido a que no confiamos en la pseudoclase de CSS, tenemos que
// establecer explícitamente la clase valid/invalid en nuestro campo de correo electrónico
addEvent(window, "load", function () {
// Aquí probamos si el campo está vacío (recuerda, el campo no es obligatorio)
// Si no es así, verificamos si su contenido es una dirección de correo electrónico con el formato correcto.
const test = email.value.length === 0 || emailRegExp.test(email.value);
email.className = test ? "valid" : "invalid";
});
// Esto define lo que sucede cuando el usuario escribe en el campo
addEvent(email, "input", function () {
const test = email.value.length === 0 || emailRegExp.test(email.value);
if (test) {
email.className = "valid";
error.innerHTML = "";
error.className = "error";
} else {
email.className = "invalid";
}
});
// Esto define lo que sucede cuando el usuario intenta enviar los datos.
addEvent(form, "submit", function () {
const test = email.value.length === 0 || emailRegExp.test(email.value);
if (!test) {
email.className = "invalid";
error.innerHTML = "I expect an e-mail, darling!";
error.className = "error active";
// Algunos navegadores antiguos no son compatibles con el método event.preventDefault ()
return false;
} else {
email.className = "valid";
error.innerHTML = "";
error.className = "error";
}
});</pre>
<p>El resultado es el siguiente:</p>
<p>{{EmbedLiveSample("Validar_formularios_sin_una_API_incorporada", "100%", 130)}}</p>
<p>Como puedes ver, no es tan difícil construir un sistema de validación por tu cuenta. La parte difícil es hacer que sea lo suficientemente genérico para que se pueda usar en diferentes plataformas y en cualquier forma. Hay muchas bibliotecas de archivos disponibles para realizar la validación de formularios, como por ejemplo <a href="http://rickharrison.github.com/validate.js/" rel="external">Validate.js</a></p>
<p>.</p>
<h2 id="Prueba_tus_habilidades!">Prueba tus habilidades!</h2>
<p>Has llegado al final de este artículo pero ¿puedes recordar la información más importante?Puedes encontrar pruebas adicionales para comprovar que has comprendido la información antes de que continue — visita <a href="/en-US/docs/Learn/Forms/Test_your_skills:_Form_validation">Prueba tus habilidades: Validación de formularios</a>.</p>
<h2 id="Resumen">Resumen</h2>
<p>La validación de formularios en el lado del cliente a veces requiere JavaScript si deseas personalizar el estilo y los mensajes de error, pero <em>siempre</em> requiere que pienses cuidadosamente en el usuario. Recuerda que siempre debes ayudar a tus usuarios a corregir los datos que proporcionan. Para ese fin, asegúrate de:</p>
<ul>
<li>Mostrar mensajes de error explícitos.</li>
<li>Ser permisivo con el formato de entrada.</li>
<li>Señalar exactamente dónde se produce el error, especialmente en formularios extensos.</li>
</ul>
<p>Una vez que hayas verificado que el formulario se ha completado correctamente, puedes proceder a enviarlo. Vamos a exponer el <a href="/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data">envío de los datos del formulario</a> en el próximo artículo.</p>
<p>{{PreviousMenuNext("Learn/Forms/UI_pseudo-classes", "Learn/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}</p>
<h2 id="En_este_módulo">En este módulo</h2>
<ul>
<li><a href="/en-US/docs/Learn/Forms/Your_first_form">Tu primer formulario</a></li>
<li><a href="/en-US/docs/Learn/Forms/How_to_structure_a_web_form">Cómo estructurar un formulario web</a></li>
<li><a href="/en-US/docs/Learn/Forms/Basic_native_form_controls">Los controles de formulario básicos originales</a></li>
<li><a href="/en-US/docs/Learn/Forms/HTML5_input_types">Los tipos de entrada en HTML5</a></li>
<li><a href="/en-US/docs/Learn/Forms/Other_form_controls">Otros controles de formulario</a></li>
<li><a href="/en-US/docs/Learn/Forms/Styling_web_forms">Aplicar estilo a formularios web</a></li>
<li><a href="/en-US/docs/Learn/Forms/Advanced_form_styling">Aplicación de estilo a formularios avanzada</a></li>
<li><a href="/en-US/docs/Learn/Forms/UI_pseudo-classes">Pseudoclases UI</a></li>
<li><a href="/en-US/docs/Learn/Forms/Form_validation">Validación de formularios en el lado del cliente</a></li>
<li><a href="/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data">Enviar los datos de un formulario</a></li>
</ul>
<h3 id="Temas_avanzados">Temas avanzados</h3>
<ul>
<li><a href="/en-US/docs/Learn/Forms/How_to_build_custom_form_controls">Cómo construir controles de formulario personalizados</a></li>
<li><a href="/en-US/docs/Learn/Forms/Sending_forms_through_JavaScript">Enviar formularios por JavaScript</a></li>
<li><a href="/en-US/docs/Learn/Forms/Property_compatibility_table_for_form_widgets">Tabla de compatibilidad de propiedades para controles de formulario</a></li>
</ul>
|