PDA

View Full Version : Validation and reg expressions



weeblexx123
Jan 4th, 2014, 02:26 PM
I am new to JS and am getting myself a little bogged down in getelementbyid and regular expressions to validate the input from forms. I have got my head around regexp's I now need to validate the input So how and in what order would I validate say 5 inputs from a form, Does any of the above make sense ?? :)

Philip M
Jan 4th, 2014, 02:57 PM
Form validation has beeen covered a zillion times in this forum. Try the serach feature of the forum.

Use document.getElementById("id").value. Note that Javascript is case-sensitive. getelementbyid will not do.

You say that have got your head around regexes. Really?

You may validate each field as soon as it has been entered, or validate all five fields in one function before the form submits. I myself prefer the former.

Be aware that form validation of the pattern if (document.formname.formfield.value == "") - that is blank - is barely worthy of the name, and virtually useless, as even a single space, an X or a ? will return false, that is pass the validation. A proper name may only contain letters, hyphen, space and apostrophe.
Numeric values, such as zip codes, phone numbers and dates, should be validated as such. Ditto email addresses. This topic has been covered many times before in this forum.

To give you the feel, here is the validation for an email address which I would probably use:-


<form id = "myform">

Email address <input type = "text" name = "email" id = "email" size = "45" onblur = "testEmail(this)">
<span id = "message" style="display:none; color:red;"> The email address is invalid - please retype it</span>

</form>

<script type = "text/javascript">
function testEmail(which) {
document.getElementById("message").style.display="none"; // hide the error message
if (!(/^([a-z0-9])([\w\.\-\+])+([a-z0-9])\@((\w)([\w\-]?)+\.)+([a-z]{2,6})$/i.test(which.value))) { // probably the best email validation regex
document.getElementById("message").style.display="inline"; // show the error message
which.value = ""; // clear the field
setTimeout("document.getElementById('email').focus()", 25); // and refocus on it
return false;
}
}
</script>


An alternative or additional way to validate email is to ask the user to enter his email address twice, and check that they match.

HTML5 provides a good many short-cuts, but of course is not yet univerally supported.
Validation of radio buttons and checkboxes requires specific approaches.

All advice is supplied packaged by intellectual weight, and not by volume. Contents may settle slightly in transit.

DaveyErwin
Jan 4th, 2014, 02:57 PM
See if this helps ...
http://www.w3schools.com/js/js_form_validation.asp

Make an html page with a form and try
to use those examples, then post back
with the code you have questions about .
Good Luck to you.

Philip M
Jan 4th, 2014, 03:05 PM
See if this helps ...
http://www.w3schools.com/js/js_form_validation.asp

Make an html page with a form and try
to use those examples, then post back
with the code you have questions about .
Good Luck to you.

Hmmm. That page suggests:-


function validateForm() {
var x=document.forms["myForm"]["fname"].value;
if (x==null || x=="")

But assigning a name to a form is obsolete (since 1997), and a form field value cannot be null, only "" (blank). And as I say above, such validation is next to useless as a single space will pass the validation. Their suggested email validation involving finding the position of . and @ is long obsolete.

Not one of w3schools best efforts! :(

But professional-standard form validation is not really a subject for beginners.

Be aware that JavaScript form validation only provides convenience for users, not security. This means that JavaScript should be used as an "enhancement", not as a requirement. So your form should not be dependent on JavaScript alone to perform your validation. Instead, whatever server-side language you use to process the form (PERL, ASP, PHP, etc.) should also perform the same validation. Otherwise, people will be able to bypass your validation (and even possibly inject malicious code) simply by disabling Javascript.

weeblexx123
Jan 4th, 2014, 03:17 PM
Hi :) Thanks Philip I will have a search, now when I said I have got my head around regexp's I meant the ones I need to validate the inputs :) not much more but I am only working with numbers and dates and times at the moment so nothing too complicated. I thought of using an external js file with all the validating functions in it and start at the top and work through the 8 values I need to check and submit them. I got confused on bolting the getElementByID and regular expression together

this is my first go

function validate()

if(!document.getElementById('RunnerID').value.match(/^[0-9]{5}(?<!00000)$/))
{
alert("Runner ID is not valid");
return false;
}

Philip M
Jan 4th, 2014, 03:39 PM
Try this:-


<script type = "text/javascript">

function validateRunner() {
var x = Number(document.getElementById('RunnerID').value) || 0; // trap NaN entries
if (/^\d{5}$/.test(x) && x >0) { // 5 digits (and nothing but) not all zeroes
// if (/^\d{1,5}$/.test(x) && x >0) { // up to 5 digits not all zeroes
alert ("OK"); // for testing
return true;
}
else {
alert ("Invalid ID"); // be aware that alerts are obsolete and should be used only for testing purposes. Use DOM methods to display a message to your users as shown above.
document.getElementById('RunnerID').value= ""; // clear the invalid field
setTimeout("document.getElementById('RunnerID').focus()", 25); // and refocus on it
return false;
}
}

</script>

felgall
Jan 4th, 2014, 09:28 PM
setTimeout("document.getElementById('RunnerID').focus()", 25); // and refocus on it

Passing strings as the first parameter to setTimeout was only ever required by an old version of Interrnet Exprorer. Version 3 I think.

All more recent browsers expect the first parameter to be a function (as that's what the standards say it should be) and when you specify a string they are then forced to eval() it into a function.

In this instance you already have a function so converting it to astring in order to get JavaScript to eval it back into a function is extra typing on your part.


setTimeout(document.getElementById('RunnerID').focus, 25); // and refocus on it

felgall
Jan 4th, 2014, 09:29 PM
setTimeout("document.getElementById('RunnerID').focus()", 25); // and refocus on it

Passing strings as the first parameter to setTimeout was only ever required by an old version of Internet Exprorer. Version 3 I think (but it may have been 2 - so long ago I can't be certain now).

All more recent browsers expect the first parameter to be a function (as that's what the standards say it should be) and when you specify a string they are then forced to eval() it into a function.

In this instance you already have a function so converting it to astring in order to get JavaScript to eval it back into a function is extra typing on your part.


setTimeout(document.getElementById('RunnerID').focus, 25); // and refocus on it

Philip M
Jan 5th, 2014, 12:37 PM
You are so right - twice!
Slip of the keyboard! :p

But you are not quite as perfect as you think - it should be

setTimeout(document.getElementById('email').focus(), 25);

weeblexx123
Jan 5th, 2014, 03:56 PM
Thanks Philip works a treat :) I hear what you say about alerts and clearing and refocusing on the field is very good. Would it be possible to replace the alert with a message next to the input box to say reinput ID or something similar ?

Philip M
Jan 5th, 2014, 04:18 PM
Thanks Philip works a treat :) I hear what you say about alerts and clearing and refocusing on the field is very good. Would it be possible to replace the alert with a message next to the input box to say reinput ID or something similar ?

I expect it would be possible.


<!DOCTYPE HTML>
<html>
<head>
<body>

Enter Runner ID <input type = "text" name = "RunnerID" id = "RunnerID" size = "5" maxlength = "5" onblur = "validateRunner()">
<span id = "message" style="display:none; font-size:10pt; color:red;"> That Runner ID is invalid - please retype it with 5 digits</span>

<script type = "text/javascript">

function validateRunner() {
document.getElementById("message").style.display="none";
var x = document.getElementById('RunnerID').value;
if (/^\d{5}$/.test(x) && x >0) { // 5 digits (and nothing but) not all zeroes
// if (/^\d{1,5}$/.test(x) && x >0) { // up to 5 digits not all zeroes
alert ("OK"); // for testing
return true;
}
else {
document.getElementById("message").style.display="inline";
document.getElementById('RunnerID').value= ""; // clear the invalid field
setTimeout(document.getElementById('RunnerID').focus(), 25); // and refocus on it
return false;
}
}

</script>

</body>
</html>

weeblexx123
Jan 5th, 2014, 08:24 PM
That works a treat thank you, but it goes wrong when I add another field to validate, if I put in a valid runner id and then put in an invalid event id, it jumps back to the runner id field and displays the invalid runner id message ?? Here is my code I can't figure out where I am going wrong ? With a single field it works fine it is just when I add a second and I have eight in total :/ Any further help would be great

<html>
<title> Test onblur </title>
<head>

<script type = "text/javascript" >
/* validate Runner ID number */
function validateRunner() {
var x = Number(document.getElementById('RunnerId').value) || 0; // trap NaN entries
if (/^\d{5}$/.test(x) && x >0) { // 5 digits (and nothing but) not all zeroes
// if (/^\d{1,5}$/.test(x) && x >0) { // up to 5 digits not all zeroes

return true;
}
else {
document.getElementById("message").style.display="inline";
document.getElementById('RunnerId').value= "";
setTimeout(document.getElementById('RunnerId').focus, 25);
return false;
}
}

/* validate EventID EventID */
function validateEventID() {
var y = Number(document.getElementById('EventID').value) || 0; // trap NaN entries
if (/^\d{5}$/.test(y) && y >0) { // 5 digits (and nothing but) not all zeroes
// if (/^\d{1,5}$/.test(y) && y >0) { // up to 5 digits not all zeroes

return true;
}
else {
document.getElementById("message").style.display="inline";
document.getElementById('EventID').value= "";
setTimeout(document.getElementById('EventID').focus, 25);
return false;
}
}
</script>

</head>
<body>

<hr/>
<h1>Submit a runner time</h1>
<hr/>
Note: all fields marked '*' are mandatory.
<p/>
<form name="submitrunnertime" method="post" action="" >

<table>
<tr><td>Runner ID*</td>
<td><input type="text" name="RunnerId" id="RunnerId" size="5" maxlength="5" onblur="validateRunner()" />
<span id = "message" style="display:none; font-size:10pt; color:red;"> That Runner ID is invalid - please retype it with 5 digits</span>
</td>
</tr>
<tr><td>Event ID*</td>
<td><input type="text" name="EventID" id="EventID" size="5" maxlength="5" onblur="validateEventID()" />
<span id = "message" style="display:none; font-size:10pt; color:red;"> That Event ID is invalid - please retype it with 5 digits</span>
</td>
</tr>
</table>
<input type="submit" name="submitrunnertime" value="submit"/>
<hr/>
</form>


</body>
</html>

felgall
Jan 5th, 2014, 09:18 PM
You are so right - twice!
Slip of the keyboard! :p

But you are not quite as perfect as you think - it should be

setTimeout(document.getElementById('email').focus(), 25);

That will work as long as you get rid of the part in blue.

When passing a function as the first parameter to setTimeout or setInterval you do NOT want to run it and pass what gets returned from the function. You want to pass the function itself.

With the () there the focus() runs immediately and what is returned from running that function is then passed to the setTimeout to run after 25 milliseconds.

Philip M
Jan 6th, 2014, 08:40 AM
That will work as long as you get rid of the part in blue.

When passing a function as the first parameter to setTimeout or setInterval you do NOT want to run it and pass what gets returned from the function. You want to pass the function itself.

With the () there the focus() runs immediately and what is returned from running that function is then passed to the setTimeout to run after 25 milliseconds.

Well, it does not work for me without the blue brackets. But I agree that with the brackets focus() is run immediately.
Nor does it work without the brackets if the SetTimeout is called by passing a function:-
setTimeout(function() {document.getElementById('email').focus()}, 25);
But setTimeout(function() {document.getElementById('email').focus()}, 5000);
works correctly to apply the focus after 5 seconds.

The short delay is intended to overcome a bug in Firefox which may no longer exist.

Philip M
Jan 6th, 2014, 09:12 AM
That works a treat thank you, but it goes wrong when I add another field to validate, if I put in a valid runner id and then put in an invalid event id, it jumps back to the runner id field and displays the invalid runner id message ?? Here is my code I can't figure out where I am going wrong ? With a single field it works fine it is just when I add a second and I have eight in total :/ Any further help would be great



You have two spans with the same id "message".

BTW, when posting here please help us to help you by making it easier to view, copy, modify, test and debug your scripts by following the posting guidelines and wrapping your code in CODE tags. This means use the octothorpe or # button on the toolbar.

felgall
Jan 6th, 2014, 10:00 AM
Well, it does not work for me without the blue brackets. But I agree that with the brackets focus() is run immediately.

With the blue brackets you may as well discard the setTimeout( ,25) part as focus() doesn't return a function for the setTimeout to run.

document.getElementById('email').focus is a function reference so there's no need to wrap it inside another function reference in order to use it with setTimeout. If setTimeout(function() {document.getElementById('email').focus()}, 5000); works then setTimeout(document.getElementById('email').focus, 5000); will also work.

Which browser is it where it fails to work with 25 but works with 5000? If 25 doesn't work then perhaps 100 will - even 100 is still to small a time interval to be noticed. I can't see why 25 wouldn't work though - I've used 5 in a setTimeout call and had it work (where it was removing the element from the page that the code was attached to and so couldn't be run immediately).