I've got a form, for which the "Send" button should only be available, upon each form field being validated. For most of my check, I call a function checkFormValue()
which is a function gathering all the simple checks, give warning where check failed, and if at least one of the check fail, disable the button. The call are made on the blur
event for each field of the form.
function checkFormValue(){
var form = document.myform;
//initializing a few variable with check, amongst them the following
//Those are example of check which are pure javascript function
var checkIDField = checkField(form.myids) && checkIDs();
//...
//This is an example of AJAX function
if(checkIDField){
checkIDValidity();
}
//Checks variables are gathered under one variable
var validform = checkIDField && CheckContactField && CheckPathsField;
var warnings = document.getElementsByClassName('warning');
var i;
var count = 0;
//Loop to check the number of warnings
for (i = 0; i < warnings.length; i++){
// Check that current character is number.
if(warnings[i].style.display===""){
count++
}
}
validform = validform && (count === 0);
document.form.send.disabled = !(validform);
}
A few check needs to be done on the server (SELECT query, check if some file exists,etc.). For those check,, I do AJAX calls, and I added in the checkFormValue()
a loop which count the number of warning displayed. If none are displayed, then the button is not disable anymore.
One of my field should contain a series of ID, in the form of a space separated list. After checking that the list is correctly formatted (list of integer separated by space, no duplicate), I want to see if those ID exist in the database. The following function set the AJAX call:
function checkIDValidity(){
var xmlhttp;
if (window.XMLHttpRequest){
//code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else{
// code for IE6, IE5
xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState===4 && xmlhttp.status===200){
var existingIDs = xmlhttp.responseText;
var idcomponent = document.myform.myids;
var idwarningdiv = document.getElementById('nonexistingid');
if(existingIDs==="Existing"){
idcomponent.setAttribute('class', 'valid');
if(idwarningdiv.style.display !== 'none'){
idwarningdiv.style.display='none';
idwarningdiv.innerHTML='';
}
}else{
idcomponent.setAttribute('class', 'invalid');
if(idwarningdiv.style.display !== ''){
idwarningdiv.style.display='';
}
if(idwarningdiv.innerHTML.substr(51,existingIDs.length)!==existingIDs){
idwarningdiv.innerHTML='<br /><img src="img/warning2.png" alt="Warning!" />'+existingIDs+' is not an existing id.';
}
}
}
};
var idnumbers = document.myform.myids.value;
var d=new Date();
//d.toUTCString() is used so the result never get cached
xmlhttp.open('GET', 'checkidvalidity.php?id='+idnumbers+'&rand='+d.toUTCString(), true);
xmlhttp.send();
}
When I enter an ID, which doesn't exist in the database, I got a warning, and if the ID is valid, the warning disappear. But the enabled/disabled status of the "Send button" is not immediately updated, on the contrary, I need to click twice on other field in the form before I can see any change on the button.
Adding a listener on the warning div for non existent IDs, triggering on propertyChanged
event and calling checkFormValue
did at first the trick, but the event is only supported on IE, and as such it didn't work on other browser. Using the mutation event "DOMAttrModified"
when it was supported, helped for Firefox and Opera.
function formLink(objectid){
var xmlhttp;
if (window.XMLHttpRequest){
//code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else{
// code for IE6, IE5
xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState===4 && xmlhttp.status===200){
document.getElementById('terminal').innerHTML=xmlhttp.responseText;
if(isDOMAttrModifiedSupported()){
document.getElementById("nonexistingid").addEventListener("DOMAttrModified",
checkFormValue,
false);
}
checkFormValue();
}
};
xmlhttp.open('GET', 'myform.php?id='+objectid, true);
xmlhttp.send();
}
Details on the isDomAttrModifiedSupported function can be found on this post about detecting if the DomAttrModified event listener is supported.
But using that approach leaves my with no solution for the WebKit browsers (Chrome, Safari). Is there a way to refactor my code so I can do my AJAX call, and it would result on an update of the disabled status of the "Send" button, without discounting the result of my other simple checks? In other word, is my validation approach correct?
PS: I get some restraints on this project, and I am not allowed to use jQuery.