06. maj 2002 - 02:57Der er
4 kommentarer og 1 løsning
Generaliseret formvalidering
Hej eksperter
Jeg har forskellige formvalidering på mit site - det er bl.a. validering af email, url, navn osv.
På nuværende tidspunkt er det lidt noget slamkode, som jeg gerne vil have generaliseret og smidt ud i en ekstern fil.
Dvs. jeg ønsker at have den essentielle valideringskode i en fil og muligheden for at kalde den med et minimum af kode fra de filer som indeholder formularer.
Mit problem er at jeg ikke helt kan gennemskue en smart måde at splitte koden op på således at jeg både får en generaliseret kode, som jeg kan bruge i forskellige formularer, men samtidig også har en kode der ikke kræver særlig meget for at kunne anvendes fra den fil der indeholder formularen - dvs. koden der bruges til at starte formvalideringen skal ikke være specielt stor!
Jeg leder efter ikke en færdig kode, men ideer og forslag til hvordan jeg opnår ovenstående.
Koden følger her: <script language="JavaScript"> <!-- //Regular Expressions to check whether email, homepage, name and country are valid //Garbage values can of course still be submitted but not really ugly garbage values :-)
var emailregexp = /^([A-Z]+)([A-Z0-9_\.\-]*)@([A-Z0-9]+)([.,_,-]([A-Z0-9]+))*\.[A-Z]{2,4}$/i var homepageregexp = /^((http|https|ftp):\/\/|)(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)\.[A-Z]{2,4}(:(\d+))?(\/)?/i var nameregexp = /^([a-z])+/i var countryregexp = /^([a-z])+/i
function isBlank(s) { var len=s.length; for(var i=0;i<len;++i) { if(s.charAt(i)!= " ") return false } return true; }
//Validate fields, submit if OK or generate proper alert message== function ValidateForm() {
if (!nameregexp.test(document.forms[0].name.value)) { alert("You have to fill in your name!"); document.forms[0].name.focus(); return false; }
if (!isBlank(document.forms[0].email.value)) { if (!emailregexp.test(document.forms[0].email.value)) { errormsg = "\"" + document.forms[0].email.value + "\" is not a valid emailaddress!\n\n"; errormsg += "It's not necessary to supply an email\nbut if you do, it has to be correct."; alert(errormsg); document.forms[0].email.focus(); return false; } } else { document.forms[0].email.value = ""; }
if (!isBlank(document.forms[0].country.value)) { if (!countryregexp.test(document.forms[0].country.value)) { errormsg = "\"" + document.forms[0].country.value + "\" is not a valid country!\n\n"; errormsg += "It's not necessary to supply a country\nbut if you do, it has to be correct."; alert(errormsg); document.forms[0].country.focus(); return false; } } else { document.forms[0].country.value = ""; }
if (!isBlank(document.forms[0].homepage.value)) { if (!homepageregexp.test(document.forms[0].homepage.value)) { errormsg = "\"" + document.forms[0].homepage.value + "\" is not a valid URL!\n\n"; errormsg += "It's not necessary to supply a homepage\nbut if you do, it has to be correct."; alert(errormsg); document.forms[0].homepage.focus(); return false; } } else { document.forms[0].homepage.value = ""; }
if (isBlank(document.forms[0].message.value)) { alert("You have to type a message!"); document.forms[0].message.focus(); return false; } document.forms[0].submit() }
//Clear all fields if user cancels the message! function ClearFields() { for (var i=0; i < document.forms[0].elements.length-2; ++i) { document.forms[0].elements[i].value = ""; } } //--> </script>
Den indlysende er vel at type-klassificere felter. Nogle af de 'tungeste' såsom email, url, real, heltal er veldefineres og kan umiddelbart gemmes i funktioner der så kaldes fra hovedprogrammet. Datoer er nogenlunde nemme hvis de blot får en formatskabelon med.
et fast format for check.funktioner:
function check<typenavn>( formElem [, hjælpeparametre ] ) { if ( typespecifik test fail ) { generer fejlmelding return false } return true; // OK }; //end check<typenavn>( Form element objekt [, ?] ) -> boolean
"Generer fejlmelding" skulle så være en struktureret udbygning af fx et array der akkumulerer fejl og tilsidst kan håndteres af formens validerings funktion.
en generel fejlklasse:
function fejlKlasse ( formElem, fejlTekst, auxdata ) { this.elem = formElem; // formelement der fejlede test this.tekst = fejlTekst; ... fejlListe[fejlListe.length] = this; // sæt fejlklassen i kø til samlet handtering. }; //end fejlklasse
engentlig ingen grund til at check funktionerne returnerer noget.
function check<typenavn>( formElem [, hjælpeparametre ] ) { if ( typespecifik test fail ) { new fejlKlasse( formElem, "fejlmelding", ??? ); // sætter fejlen i kø } }; //end check<typenavn>( Form element objekt [, ?] )
den overordnede valideringsfunktion ville så blive noget i retning af:
function valider( formObj ) { fejlListe = new Array(); checkEmail( formObj.emalfelt ); checkUrl( formObj.urlfelt ); checkDato( formObj.datofelt, "yyyy?mm?dd" ); if ( formObj.checkbox.checked ) { // lidt skæve bliver der altid :) checkDato( formObj.datofelt2, "yyyy?mm?dd" ); } ... if ( fejlListe.length == 0 ) { return true; // alles ist gut
} else { fejlListe[0].elem.focus(); // gic brugeren nogle eller alle fejlmeldinger return false; // nicht gut. } };
Stadig for løst til at implementere, men måske værd at kommentere og modellere på.
Nok det væsentligst der mangler er en god måde at haandtere relationer imellem felternes værdier. hvis formularen fx skal bruges til at købe flybillet skal udrejsedato være senere end submittidspunktet, og hvis der samtidig skal bookes hjemrejsebillet skal hjemrejseksedatoen være senere endnu.
Hvis vi lader check-funktionerne returnere det normaliserede fejltindhold i rette stype skulle det så nogenlunde du:
function checkDato( formElem, format ) { ... if ( failed ) { return false; } else { return new Date( aar, maaned, dag ); }
i vadider bliver det så:
var udDato = checkDato( formObj.datofelt, "yyyy?mm?dd" ); if ( udDato && udDato.valueOf() < (new Date()).valueOf() ) { new fejlKlasse( formObj.datofelt, "Du kan ikke tage afsted før du køber billetten" ); if ( formObj.checkbox.checked ) { // lidt skæve bliver der altid :) var hjemDato = checkDato( formObj.datofelt2, "yyyy?mm?dd" ); if ( ( udDato && hjemDato ) & hjemDato.valueOf() < udDato.valueOf() ) { new fejlKlasse( formObj.datofelt, "Du kan ikke komme hjem før du tager afsted" ); } }
Det er egentlig ikke så vældig meget der spares :(
Jeg har ikke haft tid til at kigge nærmere på dine forslag, da jeg er i gang med noget eksamenslæsning, men jeg skal nok få klemt det ind på et tidspunkt. Du skal nok få noget respons på dine forslag og hvis jeg laver noget som jeg selv er tilfreds med, vil jeg nok også poste resultatet her!
-I'll be back ;-)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.