Inputkontroll
Håndlaget eksempel
La oss anta at vi skal registrere to felter: Fødselsdato og E-post adresse. Vi lager oss en form. Denne formen sender data til et skript som bare forteller hva vi har fylt inn. Du kan teste:
Den aktuelle HTML-koden ser slik ut
<fieldset style="width:300px"> <form action="http://www.it.hiof.no/~borres/cgi-bin/demo/std.py" method="post"> <table class="normal"> <tr> <td>Født: </td> <td><input type="text" id="fdate0" name="fdate0"/></td> </tr> <tr> <td>Epost:</td><td><input type="text" id="email0" name="email0"/></td> </tr> <tr> <td> </td><td><input type="submit" value="Send"/></td> </tr> </table> </form> </fieldset>
Vi ser at verdien av action-attributten er adressen til et skript som gir oss en respons. I .Net ville action-attributten i den presenterte HTML-fila være navnet på websiden, f.eks.: Default.aspx.
Vi ønsker å legge til inputkontroll i Javascript. Vi begynner med å skrive en funksjon for hvert av de to feltene:
function controlDate(form) { var bs=form.fdate.value; document.getElementById('error_date').innerHTML=''; if (bs.length!=10) { document.getElementById('error_date').innerHTML='feil format'; return false; } var regex=/(19|20)\d\d[:](0[1-9]|1[012])[:](0[1-9]|[12][0-9]|3[01])/; if (regex.test(bs)) { return true; } document.getElementById('error_date').innerHTML='feil format'; return false; } function controlMail(form) { var ms=form.email.value; document.getElementById('error_mail').innerHTML=''; if (ms.length==0) { document.getElementById('error_mail').innerHTML='feil format'; return false; } var regex=/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; if (regex.test(ms)) { return true; } document.getElementById('error_mail').innerHTML='feil format'; return false; } function controlForm(form){ return controlDate(form) && controlMail(form); }
Vi ser at vi har brukt regulære uttrykk for å teste syntaksen. Regulære uttrykk har ikke noen spesiel plass i dette materialet, men det er greitt å finn og tilpasse regulære uttrykk for mange situasjoner. [1] , [2]
Så må vi ta stilling til to ting:
- Hvordan skal vi kalle funksjonene ? Vi velger å gjøre dette ved to begivenheter: Når et felt mister fokus (onblur) og når vi forsøker å sende formen (onclick).
- Hvordan skal vi gi feilmelding. Vi gjør med et feilmeldingsfelt knyttet til hver av inputfeltene
Den aktuelle HTML-koden ser nå slik ut
<fieldset style="width:300px"> <form action="http://www.it.hiof.no/~borres/cgi-bin/demo/std.py" method="post"> <table class="normal"> <tr> <td>Født: (åååå:mm:dd)</td> <td> <input type="text" maxlength="10" id="fdate" name="fdate" onblur="javascript:controlDate(this.form)"/></td> <td id="error_date" style="color:red"> </td> </tr> <tr> <td>Epost: (nn@a.b)</td> <td><input type="text" id="email" name="email" onblur="javascript:controlMail(this.form)"/> </td> <td id="error_mail" style="color:red"> </td> </tr> <tr> <td> </td> <td><input type="submit" value="Send" onclick="javascript:return controlForm(this.form);"/> </td> <td> </td> </tr> </table> </form> </fieldset>
Det er mange måter å gjøre dette på. I eksempelet over har jeg blandet document-modeller litt. Jeg har brukt uttrykk som form.email.value for å plukke opp verdien i E-post feltet, mens jeg har brukt document.getElementById('mail_error') for å identifisere feilmeldingsfeltet. Den første formuleringen forutsetter attributten name. Dersom jeg skulle vært konsekvent på W3C's modell, skulle jeg brukt den siste formuleringen også til å plukke opp E-post feltet, feks.: slik: document.getElementById('email').innerHTML. Selv dette er forøvrig ikke helt riktig siden jeg har brukt innerHTML som ikke er W3C standard.
Vi ser at kontrollen som er laget ovenfor plukker ikke opp ulovlige datoer. Det vil si at 2007:02:31 og 2007:04:31 vil passere. Vi kan ordne de med litt tillegg i javascriptkoden:
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 }
Automatisk løsning
Vi ønsker å løse det samme problemet i Visual Studio. Vi begynner med å lage en website og møblere den med våre to inputfelter og sendeknappen. Så lager vi et objekt av typen: RegularExpressionValidator til hver av input feltene. Vi finner at Visual Stdudio er satt opp med en ferdig regexp-uttrykk for E-post, mens dato-uttrykket må vi legge inn selv.
Inputctrl.aspx ser slik ut i Visual Studio (endring i koding gjør at æøå ser litt rare ut):
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Inputctrl.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <fieldset style="width: 510px"> Født: (åååå:mm:dd) <asp:TextBox ID="TextBox1" runat="server" MaxLength="10"></asp:TextBox> <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="TextBox1" ErrorMessage="Feil dato format" ValidationExpression="\d{4}:\d{2}:\d{2}" Width="131px"></asp:RegularExpressionValidator><br /> Epost: (nn@a.b) <asp:TextBox ID="TextBox2" runat="server" Width="194px"></asp:TextBox> <asp:RegularExpressionValidator ID="RegularExpressionValidator2" runat="server" ControlToValidate="TextBox2" ErrorMessage="Feil E-post format" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" Width="129px"> </asp:RegularExpressionValidator><br /> <br /> <asp:Button ID="Button1" runat="server" Text="Send" OnClick="Button1_Click" /><br /> </fieldset> <asp:Label ID="Label1" runat="server"></asp:Label> <div>Inspiser kildekoden for å se hvordan javascript er lagt til</div> <div><a href="javascript:history.back()">Tilbake</a></div> </form> </body> </html>
Hvis du inspiserer kildekoden vil du se hvordan Visual Studio har lagt til javaskriptkode for å foreta inputkontrollen. Det er ikke uten videre enkelt å gå inn og modifisere denne koden. Det er kanskje grunn til å gjøre en vurdering av om det er lurt å bruke automatikken i Visual studio i alle sammenhenger.
Blandet løsning
Vi forsøker å blande de to strategiene på den måten at vi lager vår egen inputkontroll på en .aspx fil.
- Vi lager en vanlig webside i Visual Studioog og møblerer den med våre to inputfelter og sendeknappen
- Kopierer den javascriptfila vi brukte i det håndlagde eksempelet
- Editerer websiden for hånd slik at den blir som vist nedenfor
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="inputctl2.aspx.cs" Inherits="inputctl2" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Inputkontroll</title> <script language="javascript" type="text/javascript" src="control.js"> </script> </head> <body> <fieldset> <form id="form1" name="form1" method="get" action="inputctl2.aspx" runat="server"> <table cellpadding="5px" cellspacing="0px" border="0px"> <tr> <td>Født: (åååå:mm:dd)</td> <td><input id="date" name="fdate" type="text" onblur="javascript:controlDate(this.form)" /></td> <td id="error_date"></td> </tr> <tr> <td>Epost: (nn@a.b)</td> <td><input id="mail" name="email" type="text" onblur="javascript:controlMail(this.form)" /></td> <td id="error_mail"></td> </tr> <tr> <td></td> <td></td> <td><input type="submit" name="Button1" value="Send" id="Button1" onclick="javascript:return controlForm(this.form)" /></td> </tr> </table> </form> </fieldset> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> </body> </html>
Javaskriptet ser slik ut:
function controlDate(form) { var bs=form.fdate.value; document.getElementById('error_date').innerHTML=''; if (bs.length!=10) { document.getElementById('error_date').innerHTML= 'feil format'; return false; } var regex=/(19|20)\d\d[:](0[1-9]|1[012])[:](0[1-9]|[12][0-9]|3[01])/; if (regex.test(bs)) { var ok=checkdate(bs); if(ok) return true; document.getElementById('error_date').innerHTML= 'datoen ekisterer ikke'; return false; } document.getElementById('error_date').innerHTML='feil format'; return false; } function checkdate(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 } function controlMail(form) { var ms=form.email.value; document.getElementById('error_mail').innerHTML=''; if (ms.length==0) { document.getElementById('error_mail').innerHTML='feil format'; return false; } var regex=/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; if (regex.test(ms)) { return true; } document.getElementById('error_mail').innerHTML='feil format'; return false; } function controlForm(form) { return controlDate(form) && controlMail(form); }
Koden som går på serveren ser slik ut:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Collections.Specialized; public partial class inputctl2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (this.IsPostBack) { NameValueCollection par=this.Request.QueryString; String met = Request.HttpMethod; Label1.Text = String.Format("Mottatt({0}): date={1}, EMail={2}", met, par["fdate"], par["email"]); } else { Label1.Text = "Here we go"; } } }