I et HTML input-element kan man skrive hvad som helst. Hvis der kræves en e-mail-adresse eller en dato, så kan ikke alle tekster accepteres. Det sparer tid, for både bruger og server, hvis teksten afvises inden formularen sendes til serveren.
Form-validering i browseren sparer denne tid på den mest hensigtsmæssige måde hvis den køres lige før formularen afsendes.
Denne side viser Javascript-kode der kan bruges til at validere formularer med, og hvordan den bruges.
Validering på klienten er ikke sikker på at blive udført.
Formålet med validering på klienten (browseren) er ikke at undvære validering på serveren. Det er kun at spare tid ved hurtigt at afvise ugyldigt input, som ellers ville blive afvist af servern.
Validering på klienten er afhængigt af Javascript. Hvis brugeren har slået Javascript fra, eller bruger en browser uden Javascript, så bliver formen sent uvalideret. Hvis det er et problem for serveren, så kan skruppelløse individer udnytte serverens svagheder ved bevidst at slå validering fra, og så sende data der udnytter problemet. Derfor skal potentielt farlige data tjekkes af serveren.
God validering blander sig så lidt som muligt, men giver så meget information som muligt. Den blokkerer ikke for gyldige data.
For at blande sig så lidt som muligt, så kalder man først valideringen når formularen er færdigudfyldt, altså lige før den afsendes. Hvis der ingen fejl er, så afsendes formularen uden videre. Hvis nogle felter er udfyldt forkert, så gives en samlet advarsel, og afsendelsen stoppes.
Den simpleste del af validering er at kalde den på det rigtige tidspunkt.
Et form
-tag har attributten onsubmit
som udføres
inden formularen afsendes. Hvis man returnerer værdien false
,
så bliver formularen ikke afsendt.
Hvis vi laver en funktion der validerer formularen, og lader den
returnere false
hvis der er fejl, så kan vi blot skrive
følgende:
<form action="..." onsubmit="return valideringsData.validate(this);">
Ved at sende this
(der refererer til form-elementet
selv) med som argument, så har funktionen nem adgang til formularen.
Man slipper for at skrive document.forms['mitFormNavn']
for at få fat i den.
Variablen valideringsData
peger på de data som
funktionen validerer formularen i forhold til. I god objektorienteret
skik er valideringsfunktionen en metode i dette objekt.
Her er en generel valideringsfunktion. I stedet for at skulle ind og ændre i funktionen hver gang man tilføjer eller fjerner input-elementer, så gemmer jeg information om formularen i et objekt.
<script type="text/javascript">
/* (C) 2003 Lasse R. Nielsen - lrn@infimum.dk
* The code may be used freely as long as this copyright notice is retained
*/
/* Class of validation data, see example for usage */
function FormValidator(dataArray) {
this.dataArray = dataArray;
}
/* Class representing a running test */
FormValidator.prototype.Test = function(){
this.errors = new Array(); // error messages
this.elemOk = new Object(); // has an element had an error
this.firstError = null; // first element with an error
};
FormValidator.prototype.Test.prototype.reportError =
function (elem,) {
this.errors[this.errors.length] = ;
this.firstError = this.firstError || elem;
};
FormValidator.prototype.Test.prototype.markError =
function markError(elem,ok) {
if (elem.length && !elem.options) { // collection, e.g., radiobuttons
for(var i=0; i < elem.length; i++) {
markError(elem[i],ok);
}
return;
}
if (!ok) {
elem.style.border = "2px solid red";
} else {
elem.style.border = "";
}
};
FormValidator.prototype.Test.prototype.result = function(){
if (this.errors.length > 0) {
alert(this.errors.join("\n"));
if (this.firstError && this.firstError.focus) {
this.firstError.focus();
}
return false;
}
return true;
};
/* the validation function itself */
FormValidator.prototype.validate = function validate(form) {
var test = new this.Test();
var data = this.dataArray;
for (var i=0; i < data.length; i++) {
// data[i] == ["elemName",function isOk(){},"Default Error Message!"]
// find element
var name = data[i][0];
var elem = form.elements[name];
if (!elem) { // no form control with that name! Panic!
continue;
}
// test element with provided function
var ok = data[i][1](elem);
// report error
if (!ok) {
test.reportError(elem,data[i][2]);
}
if (typeof ok == "string") { // Special error message
test.reportError(elem,ok);
ok = false;
}
// mark element if it has errors
if (typeof test.elemOk[name] == "undefined") {
test.elemOk[name] = ok;
} else {
ok = test.elemOk[name] = test.elemOk[elem.name] && ok;
}
test.markError(elem,ok);
}
return test.result();
}
</script>
Her er et eksempel på brugen af validerings-objektet:
<form action="..." onsubmit="return minValidering.validate(this);">
<label>Fornavn: <input type="text" name="name" /></label>
<label>Alder: <input type="text" name="age" /></label>
<label>Fødselsdag: <input type="text" name="birthday" /></label>
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
var minValidering = new FormValidator(
[["name",nonEmpty,"Fornavn skal udfyldes"],
["name",noSpace,"Fornavn må ikke indeholde mellemrum"],
["age",nonEmpty,"Alder skal udfyldes"],
["age",onlyDigits,"Alder skal være et tal"],
["birthday",isDate,"Fødselsdag skal være en dato i formatet YYYY-MM-DD"]
]);
function nonEmpty(elem) {
return elem.value != "";
}
function noSpace(elem) {
return elem.value.indexOf(" ")==-1;
}
function onlyDigits(elem) {
return /^\d*$/.test(elem.value);
}
function isDate(elem) {
if (!/^\d{4}-\d{2}-\d{2}$/.test(elem.value)) { return false; }
var parts = elem.value.split("-");
var day = new Date(+parts[0],parts[1]-1,+parts[2]);
if (day.getDate() != +parts[2] || day.getMonth() != parts[1]-1) {
return "Fødselsdatoen findes ikke. Formatet er YYYY-MM-DD.";
}
return true;
}
</script>
For hver validering man vil lave, skal man tilføje et element til arrayet. En element er selv er array på formen:
["elementNavn",testfunktion,"Fejlbesked"]
Valideringsfunktionen tager elementet med det navn og kalder
funktionen med det element som argument. Funktionen skal enten
returnere true
hvis elementets indhold godkendes, eller
false
hvis det ikke gør. Hvis indholdet ikke godkendes ,
så kan funktionen kan også vælge at returnere en streng med en speciel
fejlbesked. Ellers bruges "Fejlbesked".
Man kan teste flere ting ved det samme element. Her tests både at fornavnet ikke er tomt og at det ikke indeholder mellemrum. De to fejl udelukker hinanden, men man kan også have to fejl der begge kan optræde samtidigt. Begge fejlbeskedder bliver så vist.
Til hver test skal man have en testfunktion. I de fleste tilfælde kan man nøjes med nogle få standard-funktioner. Her er nogle eksempler:
<script type="text/javascript">
/* først en hjælpe-funktion */
// funktion til at lave funktioner der tester med et regulært udtryk
function makeRegExpTest(re) {
return function(elem) {
return re.test(elem.value);
}
}
/* Testfunktionerne */
// ikke tomt element, til text, textarea og password
function nonEmpty(elem) {
return elem.value != "";
}
// ingen mellemrum
function noSpace(elem) {
return elem.value.indexOf(" ")==-1;
}
// kun cifre
var onlyDigits = makeRegExpTest(/^\d*$/);
// telefonnummer: cifre, mellemrum og bindestreger, mindst et.
var isPhoneNumber = makeRegExpTest(/^[- \d]+$/);
// E-mail-adresse: noget@noget.noget
var isEMailAddress = makeRegExpTest(/.+@.+\..+/);
// Gyldig dato i formatet YYYY-MM-DD
// udelukker fx 30. februar
function isDate(elem) {
if (!/^\d{4}-\d{2}-\d{2}$/.test(elem.value)) {
return false; // format forkert
}
var parts = elem.value.split("-");
var day = new Date(+parts[0],parts[1]-1,+parts[2]);
if (day.getDate() != +parts[2] ||
day.getMonth() != parts[1]-1) {
return "Datoen findes ikke. Formatet er YYYY-MM-DD.";
}
return true;
}
// Mindst en checkbox eller radiobutton valgt
function isOneChecked(elem) {
if (!elem.length) { // ikke checkbox group
return elem.checked;
}
var numChecked = 0;
for (var i = 0; i < elem.length; i++) {
numChecked += elem[i].checked;
}
return (numChecked > 0);
}
// mindst en select-option valgt, til select-elementer med multiple eller size 2+
function isSelected(elem) {
return (elem.selectedIndex != -1);
}
</script>
Last modified: Tue Jan 13 01:19:06 Romance Standard Time 2004