webForumDet fria alternativet

Formulärvalidering

6 svar · 387 visningar · startad av Lynxo

LynxoMedlem sedan dec. 20064 inlägg
#1

Hej allihopa!

Jag har ett formulär med ett textfält där man ska fylla i personnummer. Vad jag undrar är: hur gör jag för att med hjälp av Javascript kontrollera att vissa sifffror är inom ett visst värde? Exempelvis ska siffrorna 3-4 ligga mellan 1-12. (Månaderna i personnumret.)

Tacksam för svar. :)

@ndersMedlem sedan juni 200032 969 inlägg
#2

Det finns en hel del script som validerar personnummer, här är ett exempel från jojoxx.net.

mvh

LynxoMedlem sedan dec. 20064 inlägg
#3

Yes, tack! Dock vill jag försöka lära mig själv också! Jag har hittills skrivit ett script som kontrollerar om det finns ett bindestreck, och om man har rätt antal tecken. Dock vill jag nu gå vidare med det sista, och kolla om vissa nummer är inom en viss intervall, och jag vill gärna förstå vad jag själv håller på med. :)

Och det var inte helt lätt att följa med i den där koden. :r Kanske någon kan förklara?

LynxoMedlem sedan dec. 20064 inlägg
#4

BTW, så här ser min kod ut hittills:

function isMailReady(form) {
var passed = false;
if (form.prsNummer.value.indexOf("-") == -1) {
alert("Bindestreck skall användas!");
}
else if (form.prsNummer.length !== 11) {
alert("Tio siffror skall användas!")
}
else {
passed = true;
}
return passed;
}

colioneMedlem sedan juni 20014 421 inlägg
#5
function personnummer(nr){
	this.valid=false;
	if(!nr.match(/^(\d{2})(\d{2})(\d{2})\-(\d{4})$/)){ return false; }
	this.now=new Date(); this.nowFullYear=this.now.getFullYear()+""; this.nowCentury=this.nowFullYear.substring(0,2); this.nowShortYear=this.nowFullYear.substring(2,4);
	this.year=RegExp.$1; this.month=RegExp.$2; this.day=RegExp.$3; this.controldigits=RegExp.$4;
	this.fullYear=(this.year*1<=this.nowShortYear*1)?(this.nowCentury+this.year)*1:((this.nowCentury*1-1)+this.year)*1;
	var months = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	if(this.fullYear%400==0||this.fullYear%4==0&&this.fullYear%100!=0){ months[1]=29; }
	if(this.month*1<1||this.month*1>12||this.day*1<1||this.day*1>months[this.month*1-1]){ return false; }
	this.alldigits=this.year+this.month+this.day+this.controldigits;
	var nn="";
	for(var n=0;n<this.alldigits.length;n++){ nn+=((((n+1)%2)+1)*this.alldigits.substring(n,n+1)); }
	this.checksum=0;
	for(var n=0;n<nn.length;n++){ this.checksum+=nn.substring(n,n+1)*1; }
	this.valid=(this.checksum%10==0)?true:false;
	this.sex=parseInt(this.controldigits.substring(2,3))%2;
}

han hanterar personnummret som ett objekt, han refererar till personnummret med this (engelska för detta.) när han anropar funktionen så frågar han efter objektets valid egenskap. Denna sätts till false från början för att senare i koden sättas till true om personnummret stämmer.

Efter dett kör han en matchning mot ett reguljärt uttryck (regular expression).

if(!nr.match(/^(\d{2})(\d{2})(\d{2})\-(\d{4})$/)){ return false; }

om nummret inte stämmer överens med mönstret som är: 2 siffror, följt av 2 siffror, följt av ytterligare 2 siffror ett bindestreck och sedan 4 siffror, returnerar funktionen false. Om den däremot stämmer överens lagras sifferföljderna i Regexp-objektet och kan nås genom att använde RegExp.$n. där n är ett heltal och RegExp.$1 motsvarar de två första siffrorna i personnummret osv. Dessa värden skickar han sedan vidare till this-objektet.

Innan han tilldelar dessa värden till this-objektet anropar han JavaScripts inbyggda Date-objekt för att plocka ut ett år med fyra siffror, hämta ut vilket sekel det är (de första två siffrorna i fyrtalsåret), sedan plockar han även ut året i "kortform". Alltså de två sista siffrorna i fyrtalsåret. All "urplockning" sker med egenskapen substring, vilket returnerar en sträng vars längd bestäms av de siffror som du anger inom parenteserna efter substring. Detta för att kunna jämföra med inskrivet värde samt att kunna avgöra om det är skottår.

Det är alltså det som sker på dessa två rader:

this.year=RegExp.$1; this.month=RegExp.$2; this.day=RegExp.$3; this.controldigits=RegExp.$4;
this.now=new Date(); this.nowFullYear=this.now.getFullYear()+""; this.nowCentury=this.nowFullYear.substring(0,2); this.nowShortYear=this.nowFullYear.substring(2,4);

Nu sker en koll om året du matat in är mindre än eller lika med värdet på "kortåret" han plockade ut via Date. Om det är det tilldelas det värdet som står till vänster om kolonet : om inte det till höger. Vänster värdet antar värdet för det sekel vi lever i (2000) plus de siffror som användaren matade in. Värdet till höger antar värdet för förra seklet (1900) och plussar på användarens år. Värdet skickas till this objektet och lagras i fullYear
Sker på denna rad:

this.fullYear=(this.year*1<=this.nowShortYear*1)?(this.nowCentury+this.year)*1:((this.nowCentury*1-1)+this.year)*1;

På nästa två rader skapar han en array med hur många dagar det finns i de olika månaderna samt gör en skottårskoll. Han tar this.fullYear och kollar om det är jämt delbara med 400. ELLER jämt delbart med 4 OCH 100, detta sker med modulus, ett tecken om ser ut som % om det är jämt delbart returnerar den noll, är det inte jämt delbart så får du en rest. Om det är jämt delbart så ändrar han värdet på months[1], där 1 är indexet för februari månad.
Så här ser det ut i JavaScript:

var months = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	if(this.fullYear%400==0||this.fullYear%4==0&&this.fullYear%100!=0){ months[1]=29; }

Nu kollar jojoxx av om man har fyllt i månaderna inom ett intervall av 1-12 samt att du inte angett för många dagar till den aktuella månaden som du är född i. Har du fyllt i fel returnerar funktionen false

if(this.month*1<1||this.month*1>12||this.day*1<1||this.day*1>months[this.month*1-1]){ return false; }

Efter detta plussar han ihop hela personnummret igen och gör om det till en checksumma. Han kollar sedan om den är jämt delbart med 10 återigen genom att använda modulus. Är den det så ändras this.valid till true.

	var nn="";
	for(var n=0;n<this.alldigits.length;n++){ nn+=((((n+1)%2)+1)*this.alldigits.substring(n,n+1)); }
	this.checksum=0;
	for(var n=0;n<nn.length;n++){ this.checksum+=nn.substring(n,n+1)*1; }
	this.valid=(this.checksum%10==0)?true:false;

Objektet har ytterligare en egenskap. Nämligen this.sex, där du får ut kontrollsiffran för om personen som matade in personnummret är tjej eller kille.

LynxoMedlem sedan dec. 20064 inlägg
#6

Tack för grymt svar!

Tror dock inte jag behöver alla de där funktionerna... ;)

Detta är vad jag har så här långt...

function isMailReady(form) {
var passed = false;
if (form.prsNummer.value.indexOf("-") == -1) {
alert("Bindestreck skall användas!");
}
if (form.prsNummer.length !== 11) {
alert("Tio siffror skall användas!")
}
if(!form.match(/^(\d{2})(\d{2})(\d{2})\-(\d{4})$/)) {
alert("Inte ett korrekt personnummer!");
}
else {
passed = true;
}
return passed;
}

Dock får jag det inte att fungera! Den kommer hela tiden till dialogrutan "Tio siffror ska användas!". Nån som vet varför?

En annan sak också. Kan man inte förenkla den tredje och sista if-satsen? Allt jag vill göra, är att kolla om nummer 3-4 ligger inom ett visst intervall (dvs 01-12). Nån som vet hur? :)

colioneMedlem sedan juni 20014 421 inlägg
#7

!== finns inte i js. funktionen för inte lika med ser ut så här: !=

133 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
130 ms — hämta tråd, inlägg och bilagor (db)