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
|
---
title: Form data validation
slug: Learn/Forms/Form_validation
translation_of: Learn/Forms/Form_validation
original_slug: Web/Guide/HTML/Forms/Form_validation
---
<div>{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms")}}</div>
<p class="summary">A validação de formulário nos ajuda a garantir que os usuários preencham os formulários no formato correto, garantindo que os dados enviados funcionem com êxito em nossos aplicativos. Este artigo apresentará conceitos e exemplos básicos sobre validação de formulário. Para mais informações adicionais, consulte o <a href="/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation">Constraint validation guide</a>.</p>
<table class="learn-box standard-table">
<tbody>
<tr>
<th scope="row">Pré-requisitos:</th>
<td>Conhecimento em informática, uma compreensão razoável de <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, e <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>.</td>
</tr>
<tr>
<th scope="row">Objetivo:</th>
<td>Entender o que é validação de formulário, por que é importante e aplicação de várias técnicas para implementá-lo.</td>
</tr>
</tbody>
</table>
<h2 id="O_que_é_validação_de_formulário">O que é validação de formulário?</h2>
<p>Vá a qualquer site popular com um formulário de registro, e perceberá que eles dão feedback quando você não insere seus dados no formato esperado. Você receberá mensagens como:</p>
<ul>
<li>"Sua senha precisa ter entre 8 e 30 caracteres e conter uma letra maiúscula, um símbolo e um número"</li>
<li>"Por favor, digite seu número de telefone no formato xxx-xxxx" (ele impõe três números seguidos por um traço, seguido por quatro números)</li>
<li>"Por favor insira um endereço de email válido" (se a sua entrada não estiver no formato "email@email.com")</li>
<li>"Este campo é obrigatório" (você não pode deixar este campo em branco)</li>
</ul>
<p>Isso é chamado de validação de formulário - quando você insere dados, o aplicativo da Web faz a verificação para ver se os dados estão corretos. Se estiver correto, o aplicativo permite que os dados sejam enviados ao servidor e (geralmente) salvos em um banco de dados; se não, você receberá uma mensagem de erro explicando quais correções precisam ser feitas. A validação de formulários pode ser implementada de várias maneiras diferentes.</p>
<p><br>
Queremos tornar o preenchimento de formulários da web o mais fácil possível. Então, por que insistimos em validar nossos formulários? Existem três razões principais:</p>
<ul>
<li><strong>Nos queremos que o dado correto e no formato correto </strong> — nossa aplicação não irá trabalhar de forma correta se os dados dos nossos usuarios estivem armazenados em formato incorreto, ou quando esses dados são omitidos.</li>
<li><strong>Quemos proteger os dados dos nossos usuários</strong> — Forçarnosos usuários a fornecer senhas seguras facilita na proteção das informações da conta do usuário.</li>
<li><strong>Queremos proteger nos mesmos</strong> — Existem diversas maneiras de um usuário malicioso usar formulários desprotegidos para danificar nossa aplicação (veja <a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a>).<br>
{{warning("Nunca confie nos dados passados do cliente para o servidor. Mesmo que seu formulário seja validado de maneira correta e previna a má formação de inputs no lado do cliente, um usuário malicioso ainda pode roubar o request da conexão.")}}</li>
</ul>
<h3 id="Different_types_of_form_validation">Different types of form validation</h3>
<p>There are two different types of form validation which you'll encounter on the web:</p>
<ul>
<li><strong>Client-side validation</strong> is validation that occurs in the browser before the data has been submitted to the server. This is more user-friendly than server-side validation as it gives an instant response. This can be further subdivided:
<ul>
<li><strong>JavaScript</strong> validation is coded using JavaScript. It is completely customizable.</li>
<li><strong>Built-in form validation</strong> using HTML5 form validation features. This generally does not require JavaScript. Built-in form validation has better performance, but it is not as customizable as JavaScript.</li>
</ul>
</li>
<li><strong>Server-side validation</strong> is validation which occurs on the server after the data has been submitted. Server-side code is used to validate the data before it is saved into the database. If the data fails authentication, a response is sent back to the client to tell the user what corrections to make. Server-side validation is not as user-friendly as client-side validation, as it does not provide errors until the entire form has been submitted. However, server-side validation is your application's last line of defence against incorrect or even malicious data. All popular <a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks">server-side frameworks</a> have features for <strong>validating</strong> and <strong>sanitizing</strong> data (making it safe).</li>
</ul>
<p>In the real world, developers tend to use a combination of client-side and server-side validation.</p>
<h2 id="Using_built-in_form_validation">Using built-in form validation</h2>
<p>One of the features of <a href="/en-US/docs/HTML/HTML5">HTML5</a> is the ability to validate most user data without relying on scripts. This is done by using <a href="/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes">validation attributes</a> on form elements, which allow you to specify rules for a form input like whether a value needs to be filled in, the minimum and maximum length of the data, whether it needs to be a number, an email address, or something else, and a pattern that it must match. If the entered data follows all the specified rules, it is considered valid; if not, it is considered invalid.</p>
<p>When an element is valid:</p>
<ul>
<li>The element matches the {{cssxref(":valid")}} CSS pseudo-class; this will let you apply a specific style to valid elements.</li>
<li>If the user tries to send the data, the browser will submit the form, provided there is nothing else stopping it from doing so (e.g., JavaScript).</li>
</ul>
<p>When an element is invalid:</p>
<ul>
<li>The element matches the {{cssxref(":invalid")}} CSS pseudo-class; this will let you apply a specific style to invalid elements.</li>
<li>If the user tries to send the data, the browser will block the form and display an error message.</li>
</ul>
<h3 id="Validation_constraints_on_input_elements_—_starting_simple">Validation constraints on input elements — starting simple</h3>
<p>In this section, we'll look at some of the different HTML5 features that can be used to validate {{HTMLElement("input")}} elements.</p>
<p>Let's start with a simple example — an input that allows you to choose your favorite fruit out of a choice of banana or cherry. This involves a simple text {{HTMLElement("input")}} with a matching label, and a submit {{htmlelement("button")}}. You can find the source code on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a>, and a live example below:</p>
<div class="hidden">
<h6 id="Hidden_code">Hidden code</h6>
<pre class="brush: html notranslate"><form>
<label for="choose">Would you prefer a banana or cherry?</label>
<input id="choose" name="i_like">
<button>Submit</button>
</form></pre>
<pre class="brush: css notranslate">input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}</pre>
</div>
<p>{{EmbedLiveSample("Hidden_code", "100%", 50)}}</p>
<p>To begin with, make a copy of <code>fruit-start.html</code> in a new directory on your hard drive.</p>
<h3 id="The_required_attribute">The required attribute</h3>
<p>The simplest HTML5 validation feature to use is the {{htmlattrxref("required", "input")}} attribute — if you want to make an input mandatory, you can mark the element using this attribute. When this attribute is set, the form won't submit (and will display an error message) when the input is empty (the input will also be considered invalid).</p>
<p>Add a <code>required</code> attribute to your input, as shown below:</p>
<pre class="brush: html notranslate"><form>
<label for="choose">Would you prefer a banana or cherry?</label>
<input id="choose" name="i_like" required>
<button>Submit</button>
</form></pre>
<p>Also, take note of the CSS included in the example file:</p>
<pre class="brush: css notranslate">input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}</pre>
<p>This causes the input to have a bright red dashed border when it is invalid, and a more subtle black border when valid. Try out the new behaviour in the example below:</p>
<p>{{EmbedLiveSample("The_required_attribute", "100%", 80)}}</p>
<h3 id="Validating_against_a_regular_expression">Validating against a regular expression</h3>
<p>Another very common validation feature is the {{htmlattrxref("pattern","input")}} attribute, which expects a <a href="/en-US/docs/JavaScript/Guide/Regular_Expressions">Regular Expression</a> as its value. A regular expression (regex) is a pattern that can be used to match character combinations in text strings, so they are ideal for form validation (as well as a variety of other uses in JavaScript).</p>
<p>Regexs are quite complex, and we do not intend to teach you them exhaustively in this article. Below are some examples to give you a basic idea of how they work:</p>
<ul>
<li><code>a</code> — matches one character that is <code>a</code> (not <code>b</code>, not <code>aa</code>, etc.)</li>
<li><code>abc</code> — matches <code>a</code>, followed by <code>b</code>, followed by <code>c</code>.</li>
<li><code>a|b</code> — matches one character that is <code>a</code> or <code>b</code>.</li>
<li><code>abc|xyz</code> — matches exactly <code>abc</code> or exactly <code>xyz</code> (but not <code>abcxyz</code>, or <code>a</code> or <code>y</code>, etc).</li>
<li>There are many more possibilities that we don't need to cover here.</li>
</ul>
<p>Anyway, let's implement an example — update your HTML to add a <code>pattern</code> attribute, like so:</p>
<pre class="brush: html notranslate"><form>
<label for="choose">Would you prefer a banana or a cherry?</label>
<input id="choose" name="i_like" required pattern="banana|cherry">
<button>Submit</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>{{EmbedLiveSample("Validating_against_a_regular_expression", "100%", 80)}}</p>
<p>In this example, the {{HTMLElement("input")}} element accepts one of two possible values: the string "banana" or the string "cherry".</p>
<p>At this point, try changing the value inside the <code>pattern</code> attribute to equal some of the examples you saw earlier, and look at how that affects the values you can enter to make the input value valid. Try writing some of your own, and see how you get on! Try to make them fruit-related where possible, so your examples make sense!</p>
<div class="note">
<p><strong>Note:</strong> Some {{HTMLElement("input")}} element types do not need a {{htmlattrxref("pattern","input")}} attribute to be validated. Specifying the <code>email</code> type for example validates the inputted value against a regular expression matching a well-formed email address (or a comma-separated list of email addresses if it has the {{htmlattrxref("multiple","input")}} attribute). As a further example, fields with the <code>url</code> type automatically require a properly-formed URL.</p>
</div>
<div class="note">
<p><strong>Note</strong>: The {{HTMLElement("textarea")}} element does not support the {{htmlattrxref("pattern","input")}} attribute.</p>
</div>
<h3 id="Constraining_the_length_of_your_entries">Constraining the length of your entries</h3>
<p>All text fields created by {{HTMLElement("input")}} or {{HTMLElement("textarea")}} can be constrained in size using the {{htmlattrxref("minlength","input")}} and {{htmlattrxref("maxlength","input")}} attributes. A field is invalid if its value is shorter than the {{htmlattrxref("minlength","input")}} value or longer than the {{htmlattrxref("maxlength","input")}} value. Browsers often don't let the user type a longer value than expected into text fields anyway, but it is useful to have this fine-grained control available.</p>
<p>For number fields (i.e. <code><input type="number"></code>), the {{htmlattrxref("min","input")}} and {{htmlattrxref("max","input")}} attributes also provide a validation constraint. If the field's value is lower than the {{htmlattrxref("min","input")}} attribute or higher than the {{htmlattrxref("max","input")}} attribute, the field will be invalid.</p>
<p>Let's look at another example. Create a new copy of the <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a> file.</p>
<p>Now delete the contents of the <code><body></code> element, and replace it with the following:</p>
<pre class="brush: html notranslate"><form>
<div>
<label for="choose">Would you prefer a banana or a cherry?</label>
<input type="text" id="choose" name="i_like" required minlength="6" maxlength="6">
</div>
<div>
<label for="number">How many would you like?</label>
<input type="number" id="number" name="amount" value="1" min="1" max="10">
</div>
<div>
<button>Submit</button>
</div>
</form></pre>
<ul>
<li>Here you'll see that we've given the <code>text</code> field a <code>minlength</code> and <code>maxlength</code> of 6 — the same length as banana and cherry. Entering less characters will show as invalid, and entering more is not possible in most browsers.</li>
<li>We've also given the <code>number</code> field a <code>min</code> of 1 and a <code>max</code> of 10 — entered numbers outside this range will show as invalid, and you won't be able to use the increment/decrement arrows to move the value outside this range.</li>
</ul>
<div class="hidden">
<pre class="notranslate">input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}
div {
margin-bottom: 10px;
}</pre>
</div>
<p>Here is the example running live:</p>
<p>{{EmbedLiveSample("Constraining_the_length_of_your_entries", "100%", 100)}}</p>
<div class="note">
<p><strong>Note</strong>: <code><input type="number"></code> (and other types, like <code>range</code>) can also take a {{htmlattrxref("step", "input")}} attribute, which specifies what increment the value will go up or down by when the input controls are used (like the up and down number buttons).</p>
</div>
<h3 id="Full_example">Full example</h3>
<p>Here is a full example to show off usage of HTML's built-in validation features:</p>
<pre class="brush: html notranslate"><form>
<p>
<fieldset>
<legend>Title<abbr title="This field is mandatory">*</abbr></legend>
<input type="radio" required name="title" id="r1" value="Mr"><label for="r1">Mr.</label>
<input type="radio" required name="title" id="r2" value="Ms"><label for="r2">Ms.</label>
</fieldset>
</p>
<p>
<label for="n1">How old are you?</label>
<!-- The pattern attribute can act as a fallback for browsers which
don't implement the number input type but support the pattern attribute.
Please note that browsers that support the pattern attribute will make it
fail silently when used with a number field.
Its usage here acts only as a fallback -->
<input type="number" min="12" max="120" step="1" id="n1" name="age"
pattern="\d+">
</p>
<p>
<label for="t1">What's your favorite fruit?<abbr title="This field is mandatory">*</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>Banana</option>
<option>Cherry</option>
<option>Apple</option>
<option>Strawberry</option>
<option>Lemon</option>
<option>Orange</option>
</datalist>
</p>
<p>
<label for="t2">What's your e-mail?</label>
<input type="email" id="t2" name="email">
</p>
<p>
<label for="t3">Leave a short message</label>
<textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
</p>
<p>
<button>Submit</button>
</p>
</form></pre>
<pre class="brush: css notranslate">body {
font: 1em sans-serif;
padding: 0;
margin : 0;
}
form {
max-width: 200px;
margin: 0;
padding: 0 5px;
}
p > label {
display: block;
}
input[type=text],
input[type=email],
input[type=number],
textarea,
fieldset {
/* required to properly style form
elements on WebKit based browsers */
-webkit-appearance: none;
width : 100%;
border: 1px solid #333;
margin: 0;
font-family: inherit;
font-size: 90%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
input:invalid {
box-shadow: 0 0 5px 1px red;
}
input:focus:invalid {
box-shadow: none;
}</pre>
<p>{{EmbedLiveSample("Full_example", "100%", 420)}}</p>
<p>See <a href="/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes">Validation-related attributes</a> for a complete list of attributes that can be used to constrain input values, and the input types that support them.</p>
<h3 id="Customized_error_messages">Customized error messages</h3>
<p>As seen in the examples above, each time the user tries to submit an invalid form, the browser displays an error message. The way this message is displayed depends on the browser.</p>
<p>These automated messages have two drawbacks:</p>
<ul>
<li>There is no standard way to change their look and feel with CSS.</li>
<li>They depend on the browser locale, which means that you can have a page in one language but an error message displayed in another language.</li>
</ul>
<table>
<caption>French versions of feedback messages on an English page</caption>
<thead>
<tr>
<th scope="col">Browser</th>
<th scope="col">Rendering</th>
</tr>
</thead>
<tbody>
<tr>
<td>Firefox 17 (Windows 7)</td>
<td><img alt="Example of an error message with Firefox in French on an English page" src="/files/4329/error-firefox-win7.png" style="height: 97px; width: 228px;"></td>
</tr>
<tr>
<td>Chrome 22 (Windows 7)</td>
<td><img alt="Example of an error message with Chrome in French on an English page" src="/files/4327/error-chrome-win7.png" style="height: 96px; width: 261px;"></td>
</tr>
<tr>
<td>Opera 12.10 (Mac OSX)</td>
<td><img alt="Example of an error message with Opera in French on an English page" src="/files/4331/error-opera-macos.png" style="height: 83px; width: 218px;"></td>
</tr>
</tbody>
</table>
<p>To customize the appearance and text of these messages, you must use JavaScript; there is no way to do it using just HTML and CSS.</p>
<p>HTML5 provides the <a href="/en-US/docs/Web/API/Constraint_validation" rel="external">constraint validation API</a> to check and customize the state of a form element. Among other things, it's possible to change the text of the error message. Let's see a quick example:</p>
<pre class="brush: html notranslate"><form>
<label for="mail">I would like you to provide me an e-mail</label>
<input type="email" id="mail" name="mail">
<button>Submit</button>
</form></pre>
<p>In JavaScript, you call the <a href="/en-US/docs/HTML/HTML5/Constraint_validation#Constraint_API's_element.setCustomValidity()"><code>setCustomValidity()</code></a> method:</p>
<pre class="brush: js notranslate">var email = document.getElementById("mail");
email.addEventListener("input", function (event) {
if (email.validity.typeMismatch) {
email.setCustomValidity("I expect an e-mail, darling!");
} else {
email.setCustomValidity("");
}
});</pre>
<p>{{EmbedLiveSample("Customized_error_messages", "100%", 80)}}</p>
<h2 id="Validating_forms_using_JavaScript">Validating forms using JavaScript</h2>
<p>If you want to take control over the look and feel of native error messages, or if you want to deal with browsers that do not support HTML's built-in form validation, you must use JavaScript.</p>
<h3 id="The_constraint_validation_API">The constraint validation API</h3>
<p>More and more browsers now support the constraint validation API, and it's becoming reliable. This API consists of a set of methods and properties available on specific form element interfaces:</p>
<ul>
<li><a href="/en-US/docs/Web/API/HTMLButtonElement">HTMLButtonElement</a></li>
<li><a href="/en-US/docs/Web/API/HTMLFieldSetElement">HTMLFieldSetElement</a></li>
<li><a href="/en-US/docs/Web/API/HTMLInputElement">HTMLInputElement</a></li>
<li><a href="/en-US/docs/Web/API/HTMLOutputElement">HTMLOutputElement</a></li>
<li><a href="/en-US/docs/Web/API/HTMLSelectElement">HTMLSelectElement</a></li>
<li><a href="/en-US/docs/Web/API/HTMLTextAreaElement">HTMLTextAreaElement</a></li>
</ul>
<h4 id="Constraint_validation_API_properties">Constraint validation API properties</h4>
<table>
<thead>
<tr>
<th scope="col">Property</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>validationMessage</code></td>
<td>A localized message describing the validation constraints that the control does not satisfy (if any), or the empty string if the control is not a candidate for constraint validation (<code>willValidate</code> is <code>false</code>), or the element's value satisfies its constraints.</td>
</tr>
<tr>
<td><code>validity</code></td>
<td>A {{domxref("ValidityState")}} object describing the validity state of the element. See that article for details of possible validity states.</td>
</tr>
<tr>
<td><code>willValidate</code></td>
<td>Returns <code>true</code> if the element will be validated when the form is submitted; <code>false</code> otherwise.</td>
</tr>
</tbody>
</table>
<h4 id="Constraint_validation_API_methods">Constraint validation API methods</h4>
<table>
<thead>
<tr>
<th scope="col">Method</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>checkValidity()</code></td>
<td>Returns <code>true</code> if the element's value has no validity problems; <code>false</code> otherwise. If the element is invalid, this method also causes an {{event("invalid")}} event at the element.</td>
</tr>
<tr>
<td>{{domxref("HTMLFormElement.reportValidity()")}}</td>
<td>Returns <code>true</code> if the element or its child controls satisfy validation constraints. When <code>false</code> is returned, cancelable {{event("invalid")}} events are fired for each invalid element and validation problems are reported to the user.</td>
</tr>
<tr>
<td><code>setCustomValidity(<em>message</em>)</code></td>
<td>Adds a custom error message to the element; if you set a custom error message, the element is considered to be invalid, and the specified error is displayed. This lets you use JavaScript code to establish a validation failure other than those offered by the standard constraint validation API. The message is shown to the user when reporting the problem.<br>
<br>
If the argument is the empty string, the custom error is cleared.</td>
</tr>
</tbody>
</table>
<p>For legacy browsers, it's possible to use a <a href="https://hyperform.js.org/" rel="external">polyfill such as Hyperform </a> to compensate for the lack of support for the constraint validation API. Since you're already using JavaScript, using a polyfill isn't an added burden to your Web site or Web application's design or implementation.</p>
<h4 id="Example_using_the_constraint_validation_API">Example using the constraint validation API</h4>
<p>Let's see how to use this API to build custom error messages. First, the HTML:</p>
<pre class="brush: html notranslate"><form novalidate>
<p>
<label for="mail">
<span>Please enter an email address:</span>
<input type="email" id="mail" name="mail">
<span class="error" aria-live="polite"></span>
</label>
</p>
<button>Submit</button>
</form></pre>
<p>This simple form uses the {{htmlattrxref("novalidate","form")}} attribute to turn off the browser's automatic validation; this lets our script take control over validation. However, this doesn't disable support for the constraint validation API nor the application of the CSS pseudo-class {{cssxref(":valid")}}, {{cssxref(":invalid")}}, {{cssxref(":in-range")}} and {{cssxref(":out-of-range")}} classes. That means that even though the browser doesn't automatically check the validity of the form before sending its data, you can still do it yourself and style the form accordingly.</p>
<p>The <a href="/en-US/docs/Accessibility/ARIA/ARIA_Live_Regions"><code>aria-live</code></a> attribute makes sure that our custom error message will be presented to everyone, including those using assistive technologies such as screen readers.</p>
<h5 id="CSS">CSS</h5>
<p>This CSS styles our form and the error output to look more attractive.</p>
<pre class="brush: css notranslate">/* This is just to make the example nicer */
body {
font: 1em sans-serif;
padding: 0;
margin : 0;
}
form {
max-width: 200px;
}
p * {
display: block;
}
input[type=email]{
-webkit-appearance: none;
width: 100%;
border: 1px solid #333;
margin: 0;
font-family: inherit;
font-size: 90%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* This is our style for the invalid fields */
input:invalid{
border-color: #900;
background-color: #FDD;
}
input:focus:invalid {
outline: none;
}
/* This is the style of our error messages */
.error {
width : 100%;
padding: 0;
font-size: 80%;
color: white;
background-color: #900;
border-radius: 0 0 5px 5px;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.error.active {
padding: 0.3em;
}</pre>
<h5 id="JavaScript">JavaScript</h5>
<p>The following JavaScript code handles the custom error validation.</p>
<pre class="brush: js notranslate">// There are many ways to pick a DOM node; here we get the form itself and the email
// input box, as well as the span element into which we will place the error message.
var form = document.getElementsByTagName('form')[0];
var email = document.getElementById('mail');
var error = document.querySelector('.error');
email.addEventListener("input", function (event) {
// Each time the user types something, we check if the
// email field is valid.
if (email.validity.valid) {
// In case there is an error message visible, if the field
// is valid, we remove the error message.
error.innerHTML = ""; // Reset the content of the message
error.className = "error"; // Reset the visual state of the message
}
}, false);
form.addEventListener("submit", function (event) {
// Each time the user tries to send the data, we check
// if the email field is valid.
if (!email.validity.valid) {
// If the field is not valid, we display a custom
// error message.
error.innerHTML = "I expect an e-mail, darling!";
error.className = "error active";
// And we prevent the form from being sent by canceling the event
event.preventDefault();
}
}, false);</pre>
<p>Here is the live result:</p>
<p>{{EmbedLiveSample("Example_using_the_constraint_validation_API", "100%", 130)}}</p>
<p>The constraint validation API gives you a powerful tool to handle form validation, letting you have enormous control over the user interface above and beyond what you can do just with HTML and CSS alone.</p>
<h3 id="Validating_forms_without_a_built-in_API">Validating forms without a built-in API</h3>
<p>Sometimes, such as with legacy browsers or <a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets">custom widgets</a>, you will not be able to (or will not want to) use the constraint validation API. In that case, you're still able to use JavaScript to validate your form. Validating a form is more a question of user interface than real data validation.</p>
<p>To validate a form, you have to ask yourself a few questions:</p>
<dl>
<dt>What kind of validation should I perform?</dt>
<dd>You need to determine how to validate your data: string operations, type conversion, regular expressions, etc. It's up to you. Just remember that form data is always text and is always provided to your script as strings.</dd>
<dt>What should I do if the form does not validate?</dt>
<dd>This is clearly a UI matter. You have to decide how the form will behave: Does the form send the data anyway? Should you highlight the fields which are in error? Should you display error messages?</dd>
<dt>How can I help the user to correct invalid data?</dt>
<dd>In order to reduce the user's frustration, it's very important to provide as much helpful information as possible in order to guide them in correcting their inputs. You should offer up-front suggestions so they know what's expected, as well as clear error messages. If you want to dig into form validation UI requirements, there are some useful articles you should read:
<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></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></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></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></li>
</ul>
</dd>
</dl>
<h4 id="An_example_that_doesnt_use_the_constraint_validation_API">An example that doesn't use the constraint validation API</h4>
<p>In order to illustrate this, let's rebuild the previous example so that it works with legacy browsers:</p>
<pre class="brush: html notranslate"><form>
<p>
<label for="mail">
<span>Please enter an email address:</span>
<input type="text" class="mail" id="mail" name="mail">
<span class="error" aria-live="polite"></span>
</label>
<p>
<!-- Some legacy browsers need to have the `type` attribute
explicitly set to `submit` on the `button`element -->
<button type="submit">Submit</button>
</form></pre>
<p>As you can see, the HTML is almost the same; we just removed the HTML validation features. Note that <a href="/en-US/docs/Accessibility/ARIA">ARIA</a> is an independent specification that's not specifically related to HTML5.</p>
<h5 id="CSS_2">CSS</h5>
<p>Similarly, the CSS doesn't need to change very much; we just turn the {{cssxref(":invalid")}} CSS pseudo-class into a real class and avoid using the attribute selector that does not work on Internet Explorer 6.</p>
<pre class="brush: css notranslate">/* This is just to make the example nicer */
body {
font: 1em sans-serif;
padding: 0;
margin : 0;
}
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%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* This is our style for the invalid fields */
input.invalid{
border-color: #900;
background-color: #FDD;
}
input:focus.invalid {
outline: none;
}
/* This is the style of our error messages */
.error {
width : 100%;
padding: 0;
font-size: 80%;
color: white;
background-color: #900;
border-radius: 0 0 5px 5px;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.error.active {
padding: 0.3em;
}</pre>
<h5 id="JavaScript_2">JavaScript</h5>
<p>The big changes are in the JavaScript code, which needs to do much more of the heavy lifting.</p>
<pre class="brush: js notranslate">// There are fewer ways to pick a DOM node with legacy browsers
var form = document.getElementsByTagName('form')[0];
var email = document.getElementById('mail');
// The following is a trick to reach the next sibling Element node in the DOM
// This is dangerous because you can easily build an infinite loop.
// In modern browsers, you should prefer using element.nextElementSibling
var error = email;
while ((error = error.nextSibling).nodeType != 1);
// As per the HTML5 Specification
var emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
// Many legacy browsers do not support the addEventListener method.
// Here is a simple way to handle this; it's far from the only one.
function addEvent(element, event, callback) {
var previousEventCallBack = element["on"+event];
element["on"+event] = function (e) {
var output = callback(e);
// A callback that returns `false` stops the callback chain
// and interrupts the execution of the event callback.
if (output === false) return false;
if (typeof previousEventCallBack === 'function') {
output = previousEventCallBack(e);
if(output === false) return false;
}
}
};
// Now we can rebuild our validation constraint
// Because we do not rely on CSS pseudo-class, we have to
// explicitly set the valid/invalid class on our email field
addEvent(window, "load", function () {
// Here, we test if the field is empty (remember, the field is not required)
// If it is not, we check if its content is a well-formed e-mail address.
var test = email.value.length === 0 || emailRegExp.test(email.value);
email.className = test ? "valid" : "invalid";
});
// This defines what happens when the user types in the field
addEvent(email, "input", function () {
var test = email.value.length === 0 || emailRegExp.test(email.value);
if (test) {
email.className = "valid";
error.innerHTML = "";
error.className = "error";
} else {
email.className = "invalid";
}
});
// This defines what happens when the user tries to submit the data
addEvent(form, "submit", function () {
var 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";
// Some legacy browsers do not support the event.preventDefault() method
return false;
} else {
email.className = "valid";
error.innerHTML = "";
error.className = "error";
}
});</pre>
<p>The result looks like this:</p>
<p>{{EmbedLiveSample("An_example_that_doesn't_use_the_constraint_validation_API", "100%", 130)}}</p>
<p>As you can see, it's not that hard to build a validation system on your own. The difficult part is to make it generic enough to use it both cross-platform and on any form you might create. There are many libraries available to perform form validation; you shouldn't hesitate to use them. Here are a few examples:</p>
<ul>
<li>Standalone library
<ul>
<li><a href="http://rickharrison.github.com/validate.js/" rel="external">Validate.js</a></li>
</ul>
</li>
<li>jQuery plug-in:
<ul>
<li><a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/" rel="external">Validation</a></li>
</ul>
</li>
</ul>
<h4 id="Remote_validation">Remote validation</h4>
<p>In some cases, it can be useful to perform some remote validation. This kind of validation is necessary when the data entered by the user is tied to additional data stored on the server side of your application. One use case for this is registration forms, where you ask for a username. To avoid duplication, it's smarter to perform an AJAX request to check the availability of the username rather than asking the user to send the data, then send back the form with an error.</p>
<p>Performing such a validation requires taking a few precautions:</p>
<ul>
<li>It requires exposing an API and some data publicly; be sure it is not sensitive data.</li>
<li>Network lag requires performing asynchronous validation. This requires some UI work in order to be sure that the user will not be blocked if the validation is not performed properly.</li>
</ul>
<h2 id="Conclusion">Conclusion</h2>
<p>Form validation does not require complex JavaScript, but it does require thinking carefully about the user. Always remember to help your user to correct the data they provide. To that end, be sure to:</p>
<ul>
<li>Display explicit error messages.</li>
<li>Be permissive about the input format.</li>
<li>Point out exactly where the error occurs (especially on large forms).</li>
</ul>
<p>{{PreviousMenuNext("Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms")}}</p>
<h2 id="In_this_module">In this module</h2>
<ul>
<li><a href="/en-US/docs/Learn/HTML/Forms/Your_first_HTML_form">Your first HTML form</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/How_to_structure_an_HTML_form">How to structure an HTML form</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/The_native_form_widgets">The native form widgets</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data">Sending form data</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/Form_validation">Form data validation</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets">How to build custom form widgets</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript">Sending forms through JavaScript</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/HTML_forms_in_legacy_browsers">HTML forms in legacy browsers</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/Styling_HTML_forms">Styling HTML forms</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/Advanced_styling_for_HTML_forms">Advanced styling for HTML forms</a></li>
<li><a href="/en-US/docs/Learn/HTML/Forms/Property_compatibility_table_for_form_widgets">Property compatibility table for form widgets</a></li>
</ul>
|