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.