...

View Full Version : universal form validation - focus on 1st error field



apoole7
08-03-2006, 02:35 PM
I have managed to create a very basic form validation script that I can retrospectively add into current forms with the least effort.

As far as the validation goes I am sure that the script is not pretty, but it does work. However, I have failed to manage to get it to return the focus to the first field that errors.

My abortive attempts are not included in the attached script because I have tried and failed with many different attempts that I have confused myself.

I would appreciate any advice that could point me in the right direction to place the focus in the first error field found.

Regards

Andy


<script language="javaScript" type="text/javaScript">
function checkForm(f,arr,obg,ebg){
//checkForm(form name, required field desc array, old bg colour, error bg colour)
var errMessage = 'Please fix the following:\n\n';
var objTemp;
var strName = ''
var boolIsValid = true;
var reqCount = 0; //count required fields to allow description to be submitted
for ( var i = 0; i < f.elements.length; i++ ) {
objTemp = f.elements[i];
strName = objTemp.name;
remove_XS_whitespace(f.elements[i]);
if ( strName.substr(strName.length - 9 ) == '_required' ) {
//change bg colour back to original
f.elements[i].style.background = obg;
if ( objTemp.value == '' ) {
boolIsValid = false;
//populate error message with meaningful field description
errMessage += arr[reqCount] + ' is empty\n';
//change bg colour to error colour
f.elements[i].style.background = ebg;
}
reqCount++;
}
}
if ( boolIsValid == true ) {
for ( var i = 0; i < f.elements.length; i++ ) {
objTemp = f.elements[i];
strName = objTemp.name;
if ( strName.substr(strName.length - 9 ) == '_required' ) {
//remove _required from field name before submitting
strName = strName.replace( /_required/, '' );
f.elements[i].name = strName;
}
}
return true;
} else {
alert( errMessage );
return false;
}
}
function remove_XS_whitespace(item){
var tmp = "";
var item_length = item.value.length;
var item_length_minus_1 = item.value.length - 1;
for (index = 0; index < item_length; index++){
if (item.value.charAt(index) != ' '){
tmp += item.value.charAt(index);
}else{
if (tmp.length > 0){
if (item.value.charAt(index+1) != ' ' && index != item_length_minus_1){
tmp += item.value.charAt(index);
}
}
}
}
item.value = tmp;
return item.value;
}
function submitForm(s){
//change submit button value to aid in prevention of multiple submissions
s.value = "...";
return true;
}
</script>

<script language="javaScript" type="text/javaScript">
//array of required field descriptions
reqDescs = new Array('test_1_field1' , 'test_2_field2' , 'test_3_field3' , 'test_4_field5');
</script>

<form id="testform" method="GET" name="testform" action="<?=$_SERVER['PHP_SELF'];?>" onSubmit="return submitForm(this.submitbutton)">
<input type="hidden" name="hidden_1" value="do" />
<input type="hidden" name="hidden_2" value="hidden_2" />
<input type="hidden" name="hidden_3" value="hidden_3" />
<input type="hidden" name="hidden_4" value="hidden_4" />
field 1:<input type="text" style="background:#eaeaea;" id="field_1_required" name="field_1_required" /><br />
field 2:<input type="text" style="background:#eaeaea;" id="field_2_required" name="field_2_required" /><br />
field 3:<input type="text" style="background:#eaeaea;" id="field_3_required" name="field_3_required" /><br />
field 4:<input type="text" style="background:#eaeaea;" id="field_4" name="field_4" /><br />
field 5:<input type="text" style="background:#eaeaea;" id="field_15_required" name="field_5_required" /><br />
Submit:<input type="submit" name="submitbutton" value="test" onclick="return checkForm(document.testform, reqDescs,'#eaeaea','#efa5a8')"/>
</form>

Pyth007
08-03-2006, 04:00 PM
To give focus to an object, use the focus() method. Thus I would try the following....
1) Have a variable that hold the name of the element that errors. (eg errObj)
2) In the first loop where you check "_required", just set the variable errObj to the name of the element that was empty.
3) Then in the last check, call:


if (boolIsValid) { ... } else {
alert( errMessage );
document.getElementById(errObj).focus();
return false;
}

A few things to note, however....
1) As written, this would actually return the user to the last error, since objErr would keep being overwritten for each error. A way around that would be to "break;" out of the loop if one of the required fields was empty (this would also tend to speed up the script since it would stop going through the form that it already "knew" was wrong).
2) Since you'd be using objErr, the existence of anything inside the variable would indicate that an error had occured; hence it could be used in place of boolIsValid (eg "if (objErr=='')...").
3) If I remember correctly, IE has a problem with going to an element using focus() directly. It needs a slight delay to finish the function before changing the focus. Thus you may need to change the last step to:


setTimeout("document.getElementById(errObj).focus();", 100);

This will give a tenth-of-a-second delay which should be enough time to finish the function without having the user notice the delay.

apoole7
08-03-2006, 04:45 PM
Pyth007,

Many thanks for your reply.

It is along the lines of what I had attempted. I was ideally hoping to get away from breaking out of the loop, only for the reason that it annoys me when I fill forms in incorrectly and I get repeated errors, I would prefer to correct all the problems I had to fix in one go.

I was hoping that I could show all errors, return the form focus to the first one and let the user then make the corrections.

Would it make sense to make your errObj an array of all errors and then reference:
document.getElementById(errObj[0]).focus();

I will give this a try, as well as adding in your ie fix, whilst I have seen the light of FF, all the users that this is for on our intranet use IE.

Thanks again

Andy

apoole7
08-03-2006, 05:12 PM
Pyth007,

Thanks for your help with this, it is appreciated. A workable solution was forthcoming from another forum which I will detail below. My attempts at array populating failed, more due to my coding rather than concept I fear.
Again many thanks

Andy


function checkForm(f,arr,obg,ebg){
//checkForm(form name, required field desc array, old bg colour, error bg colour)
var errMessage = 'Please fix the following:\n\n';
var firstBombObj = null;
var objTemp;
var strName = ''
var boolIsValid = true;
var reqCount = 0; //count required fields to allow description to be submitted
for ( var i = 0; i < f.elements.length; i++ ) {
objTemp = f.elements[i];
strName = objTemp.name;
remove_XS_whitespace(f.elements[i]);
if ( strName.substr(strName.length - 9 ) == '_required' ) {
//change bg colour back to original
f.elements[i].style.background = obg;
if ( objTemp.value == '' ) {
boolIsValid = false;
//set first error
if(firstBombObj==null){
firstBombObj = objTemp;
}
//populate error message with meaningful field description
errMessage += arr[reqCount] + ' is empty\n';
//change bg colour to error colour
f.elements[i].style.background = ebg;
}
reqCount++;
}
}
if ( boolIsValid == true ) {
for ( var i = 0; i < f.elements.length; i++ ) {
objTemp = f.elements[i];
strName = objTemp.name;
if ( strName.substr(strName.length - 9 ) == '_required' ) {
//remove _required from field name before submitting
strName = strName.replace( /_required/, '' );
f.elements[i].name = strName;
}
}
return true;
} else {
alert( errMessage );
firstBombObj.focus();
return false;
}
}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum