Inputkontroll
Et enkelt eksempel
Vi begynner med et enkelt eksempel som ikke stiller store krav til selve kontrollen, valideringen. Hensikten er å se litt på organisering og rekkefølge. Vi tar for oss en situasjon der brukeren inviteres til å angi en 4-siffret tallkode og en tekst med 3 bokstaver.
Strategien er at vi skriver og kaller tre funksjoner slik:
- controlnumber(). Denne kalles når sifferfeltet mister fokus, begivenheten onblur. Denne setter opp en feilmelding og returnerer false dersom noe er galt i sifferfeltet, ellers true.
- controlalfa(). Denne kalles når bokstavfeltet mister fokus, begivenheten onblur. Denne setter opp en feilmelding og returnerer false dersom noe er galt i bokstavfeltet, ellers true.
- controlboth(). Denne kalles når vi trykker på Registrer-knappen, begivenheten onsubmit, og kaller de to andre funksjonene. Denne returnerer false dersom en av de to andre returnerer false, ellers true.
function controlnumber()
{
inputelt=document.getElementById('number');
errorelt=document.getElementById('numbererror');
if ((inputelt.value==null) || (inputelt.value.length!=4))
{
errorelt.innerHTML='4 siffere';
return false;
}
var legals = "0123456789";
var T=inputelt.value;
for (i = 0; i != T.length; i++)
if (legals.indexOf(T.charAt(i)) == -1)
{
errorelt.innerHTML='bare siffere';
return false;
}
errorelt.innerHTML='';
return true;
}
function controlalfa()
{
inputelt=document.getElementById('alfa');
errorelt=document.getElementById('alfaerror');
if ((inputelt.value==null) || (inputelt.value.length!=3))
{
errorelt.innerHTML='3 bokstaver';
return false;
}
var legals = "abcdefghijklmopqrstuvwxyzæøå";
var T=inputelt.value;
T=T.toLowerCase()
for (i = 0; i != T.length; i++)
if (legals.indexOf(T.charAt(i)) == -1)
{
errorelt.innerHTML='bare bokstaver';
return false;
}
errorelt.innerHTML='';
return true;
}
function controlboth(){
if (!controlalfa())
return false;
if (!controlnumber())
return false;
return true;
}
Den aktuelle HTML-koden er som nedenfor. Det kan virke litt overdrevet med table, men hensikten er å ordne de tre komponentene inledningstekst, selve inputfeltet og feilmeldingen.
<fieldset>
<legend>Registrer dine data</legend>
<form onsubmit="javascript:return controlboth();"
action="http://www.it.hiof.no/~borres/cgi-bin/forms/scriptvalidate1.py"
method="post">
<table class="normal">
<tr>
<td>Tall:(4 siffer)</td>
<td><input id="number" name="siffere" onblur="controlnumber()"
type="text" value="" maxlength="4" size="10"/></td>
<td id="numbererror" style="color:red"> </td>
</tr>
<tr>
<td>Tekst:(3 bokstaver)</td>
<td><input id="alfa" name="bokstaver" onblur="controlalfa()"
type="text" value="" maxlength="3" size="10"/></td>
<td id="alfaerror" style="color:red"> </td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Registrer"/></td>
<td> </td>
</tr>
</table>
</form>
</fieldset>
Merk onsubmit i form-elementet. Dersom controlboth() returnerer false dreper vi submitforsøket.
Et eksempel til
Vi lager et eksempel til der vi bruker regulæruttrykk for å validere input.
Den aktuelle JavaScript-funksjonen ser slik ut:
function controldato()
{
inputelt=document.getElementById('dato');
errorelt=document.getElementById('datoerror');
if ((inputelt.value==null) || (inputelt.value.length!=10))
{
errorelt.innerHTML='galt format';
return false;
}
var T=inputelt.value;
var regex=/(19|20)\d\d[:](0[1-9]|1[012])[:](0[1-9]|[12][0-9]|3[01])/;
if (regex.test(T))
{
errorelt.innerHTML='';
return true;
}
errorelt.innerHTML='galt format';
return false;
}
Vi ser at vi har brukt regulære uttrykk, regex-objektet, til å teste formatet. Vi kunne gjort dette med ren string-programmering (split, lengde kontroll osv), men den løsningen som er valgt er vesentlig smidigere.
Den aktuelle HTML-koden er etter mønster av forrige eksempel slik:
<fieldset>
<legend>Registrer dato</legend>
<form onsubmit="javascript:return controldato();"
action="http://www.it.hiof.no/~borres/cgi-bin/forms/scriptvalidate2.py"
method="post">
<table class="normal">
<tr>
<td>Dato:(åååå:mm:dd)</td>
<td><input id="dato" name="dato" onblur="controldato()"
code="text" value="" maxlength="10" size="11"/></td>
<td id="datoerror" style="color:red"></td>
</tr>
<tr>
<td></td>
<td><input code="submit" value="Registrer"/></td>
<td></td>
</tr>
</table>
</form>
</fieldset>
Nå har vi laget en ren syntakskontroll av datoformatet.
var regex=/(19|20)\d\d[:](0[1-9]|1[012])[:](0[1-9]|[12][0-9]|3[01])/;
Løsningen har noen svakheter. F.eks. vil 2006:02:31 passere syntakskontrollen selv om det er en dato som ikke finnes. På den annen side vil 1889:02:01 feile siden regulæruttrykket vårt bare aksepterer datoer på 1900 og 2000 tallet.
La oss anta at vi bare er intresserte i datoer på 1900 og 2000 tallet.
Det andre problemet, altså å fange opp problemer av typen 2001:02:31, kan vi løse på flere måter. Vi kan utvide regex-uttrykket og fange det opp der eller vi kan skrive string-kode. Vi prøver det siste, og lage følgende funksjoner:
function controldatox()
{
inputelt=document.getElementById('datox');
errorelt=document.getElementById('datoerrorx');
if ((inputelt.value==null) || (inputelt.value.length!=10))
{
errorelt.innerHTML='galt format';
return false;
}
var T=inputelt.value;
var regex=/(19|20)\d\d[:]\d\d[:]\d\d/;
if (regex.test(T))
{
if(checkdato(T))
{
errorelt.innerHTML='';
return true;
}
else
{
errorelt.innerHTML='datoen eksisterer ikke';
return false;
}
}
errorelt.innerHTML='galt format eller galt årstall';
return false;
}
function checkdato(s){
var strArray=s.split(":");
y=parseInt(strArray[0]);
m=parseInt(strArray[1]);
d=parseInt(strArray[2]);
if ((m==1)||(m==3)||(m==5)||(m==7)||(m==8)||(m==10)||(m== 12))
{
return (d <= 31);
}
else if ((m==4)||(m==6)||(m==9)||(m==11))
{
return (d <= 30);
}
else if (m == 2)
{
if (d <= 28)
return true;
if (d > 29)
return false;
// d==29
if ((y % 4 == 0) && (y % 100 != 0))
return true;
return false;
}
else
return false
}
Test denne:
Et mer komplisert eksempel
Utgangspunktet er at brukeren ønsker å endre sitt passord. Det gjøres ikke annet enn lengdekontroll på brukernavnet og det gamle passordet.