I am a total newbie to JavaScript, trying to find my way on form validation. I have been reading books as well as online tutorials and I found the following code online that is, in my opinion, very elegant and maintainable. Unfortunately, my skills in JavaScript are not good enough to understand everything. I am here to ask your help to understand the different functions defined.
I would like also to call the InstantValidation function on an event (onSubmit event) calling it in an independent .js file (based on event listener), so might you please also help me to call the function appropriately?
Here is the code:
<html>
<body>
<form id="myform" action="#" method="get">
<fieldset>
<legend><strong>Add your comment</strong></legend>
<p>
<label for="author">Name <abbr title="Required">*</abbr></label>
<input name="author" id="author" value=""
required="required" aria-required="true"
pattern="^([- \w\d\u00c0-\u024f]+)$"
title="Your name (no special characters, diacritics are okay)"
type="text" spellcheck="false" size="20" />
</p>
<p>
<label for="email">Email <abbr title="Required">*</abbr></label>
<input name="email" id="email" value=""
required="required" aria-required="true"
pattern="^(([-\w\d]+)(\.[-\w\d]+)*@([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})$"
title="Your email address"
type="email" spellcheck="false" size="30" />
</p>
<p>
<label for="website">Website</label>
<input name="website" id="website" value=""
pattern="^(http[s]?:\/\/)?([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2}(\/([-~%\.\(\)\w\d]*\/*)*(#[-\w\d]+)?)?$"
title="Your website address"
type="url" spellcheck="false" size="30" />
</p>
<p>
<label for="text">Comment <abbr title="Required">*</abbr></label>
<textarea name="text" id="text"
required="required" aria-required="true"
title="Your comment"
spellcheck="true" cols="40" rows="10"></textarea>
</p>
</fieldset>
<fieldset>
<button name="preview" type="submit">Preview</button>
<button name="save" type="submit">Submit Comment</button>
</fieldset>
</form>
<script type="text/javascript">
(function()
{
//add event construct for modern browsers or IE
//which fires the callback with a pre-converted target reference
function addEvent(node, type, callback)
{
if(node.addEventListener)
{
node.addEventListener(type, function(e)
{
callback(e, e.target);
}, false);
}
else if(node.attachEvent)
{
node.attachEvent('on' + type, function(e)
{
callback(e, e.srcElement);
});
}
}
//identify whether a field should be validated
//ie. true if the field is neither readonly nor disabled,
//and has either "pattern", "required" or "aria-invalid"
function shouldBeValidated(field)
{
return (
!(field.getAttribute('readonly') || field.readonly)
&&
!(field.getAttribute('disabled') || field.disabled)
&&
(
field.getAttribute('pattern')
||
field.getAttribute('required')
)
);
}
//field testing and validation function
function instantValidation(field)
{
//if the field should be validated
if(shouldBeValidated(field))
{
//the field is invalid if:
//it's required but the value is empty
//it has a pattern but the (non-empty) value doesn't pass
var invalid =
(
(field.getAttribute('required') && !field.value)
||
(
field.getAttribute('pattern')
&&
field.value
&&
!new RegExp(field.getAttribute('pattern')).test(field.value)
)
);
//add or remove the attribute is indicated by
//the invalid flag and the current attribute state
if(!invalid && field.getAttribute('aria-invalid'))
{
field.removeAttribute('aria-invalid');
}
else if(invalid && !field.getAttribute('aria-invalid'))
{
field.setAttribute('aria-invalid', 'true');
}
}
}
//now bind a delegated change event
//== THIS FAILS IN INTERNET EXPLORER <= 8 ==//
//addEvent(document, 'change', function(e, target)
//{
// instantValidation(target);
//});
//now bind a change event to each applicable for field
var fields = [
document.getElementsByTagName('input'),
document.getElementsByTagName('textarea')
];
for(var a = fields.length, i = 0; i < a; i ++)
{
for(var b = fields[i].length, j = 0; j < b; j ++)
{
addEvent(fields[i][j], 'change', function(e, target)
{
instantValidation(target);
});
}
}
})();
</script>
</body>
</html>
In particular, the following code is not toally clear to me:
function addEvent(node, type, callback)
{
if(node.addEventListener)
{
node.addEventListener(type, function(e)
{
callback(e, e.target);
}, false);
}
else if(node.attachEvent)
{
node.attachEvent('on' + type, function(e)
{
callback(e, e.srcElement);
});
}
}
Any help (even a very brief explanation) would be highly appreciated !
That one code section acts as an event handler, but works across various different browsers.
Most browsers use the addEventListener
way of adding an event handler.
Some Internet Explorer versions use attachEvent
: http://msdn.microsoft.com/en-us/library/ie/ms536343(v=vs.85).aspx
The function allows both ways to be used.
It has you pass in...
node
)type
)callback
)Browser events: http://eloquentjavascript.net/chapter13.html
Abstraction layers: http://en.wikipedia.org/wiki/Abstraction_layer
Browser events are things like a page fulling loading (onload
), something being clicked (onclick
), an input being changed (onchange
), a cursor going over an element (onmouseover
), etc...
http://www.w3schools.com/js/js_htmldom_events.asp
onSubmit
...//now bind a change event to each applicable for field
The code below that goes through each input
and textarea
element and adds validation to each one with the onchange
event. But what you want to do is validate onsubmit
, which requires something like this, below the other addEvent
call:
addEvent("myform","onsubmit", function(){
//de Go field by field and validate.
//de If all the fields pass, return true.
//de If one or more fields fail, return false.
})
If you want, you can even remove the onChange
events. That is your choice. The main thing here is that you need to make sure to only validate the fields inside the form itself, which you can look at this answer for more information about: Best Practice: Access form elements by HTML id or name attribute? ... loop through all the elements, and validate each one within the addEvent
I mentioned above which must return true
or false
to either allow the form to be submitted, or stop the submission and show that there were validation errors.
Please remember! As a personal bit of advice... On the server-side you still want to do validation, even if you have client-side validation. Browsers are easy to manipulate, so you might still have bad data sent to the server. Always, always do server-side validation regardless of client-side.
It just looks like a cross-browser function that attaches a handler (instantValidation
) to the "change" or "onchange" events of all input and textarea controls.
I say cross-browser because of the presence of two separate event subscription methods. attachEvent
is for older IE browsers (5-8) and addEventListener
is generally for all modern browsers.
This addEvent
function checks for the presence of said functions and uses whatever is available, giving preference to the "modern" way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With