1
\$\begingroup\$

I want to know if this would be considered a proper way to validate a form or if there is an easier way that I'm not aware of.

I think I was reading somewhere that you are not supposed to use isNaN with AJAX but this seems to work for me. Can I just leave as is since it works or is there a better structure/system that I should be following?

function AjaxPost () {

    // Declaring my variables
    var xmlhttp;
    var url = "weight_p.php";
    var age = document.getElementById("age").value;
    var height_ft = document.getElementById("height_ft").value;
    var height_in = document.getElementById("height_in").value;
    var weight = document.getElementById("weight").value;
    var gender = document.getElementById("gender").value;
    var activity = document.getElementById("activity").value;

    // Validate all values entered
    if (age == "" || isNaN(age)) {
        alert("Please insert age, must be numerical!");
        return false;
    }
    if (height_ft == "" || height_in == "" || isNaN(height_ft) || isNaN(height_in)) {
        alert("Please insert height, must be numerical!");
        return false;
    }
    if (weight == "" || isNaN(weight)) {
        alert("Please enter weight, must be numerical!");
        return false;
    }
    if (gender == "") {
        alert("Please select gender");
        return false;
    }
    if (activity == "") {
        alert("Please select activity level!");
        return false;
    }
    // These are all the values we are sending
    var info = "age="+age+"&height_ft="+height_ft+"&height_in="+height_in+"&weight="+weight+"&gender="+gender+"&activity="+activity;
    // Check to see if browser is compatable
    if (window.XMLHttpRequest) {
        // IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {
        // IE6, IE5, and older browsers
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.open("POST", url, true);

    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                var return_data = xmlhttp.responseText;
                document.getElementById("status").innerHTML = return_data;
            }
        }

    xmlhttp.send(info);
    document.getElementById("status").innerHTML = "Processing....";
}
\$\endgroup\$
1
  • \$\begingroup\$ There are a number of html input types that can help you to do the job (as well as sometimes providing a better interface for the user) and also there is the "required" attribute for input tags which can help you to assert that the user enters something. If you truly want custom JS form validation, there are also many javascript form validation libraries available that can help you to keep your code clean. In html5 you can also use the pattern attribute in combination with the title attribute to match specific patterns and provide helpful messages if they aren't matched. \$\endgroup\$
    – Shashank
    Jun 10, 2015 at 17:59

1 Answer 1

2
\$\begingroup\$

For a problem like this, I would try to find a way to use loops to make it easier to add and remove things from your form. Right now, if you want to add something, you have to go through and edit almost every part of your code.

I find that the easiest way to get these things into loops would be to create objects for each form element:

function FormElement(name, isNumber) {
    this.name = name;
    this.val = document.getElementById(name);
    this.isNumber = isNumber;
}

Then, the top of your function would look like this:

var age = new FormElement("age", true);

...

var gender = new FormElement("gender", false);

And, to make iterating easier, let's stick these in an array:

var formElements = [age, height_ft, height_in, weight, gender, activity];

Now, all we have to do is iterate through them and check their properties:

for(var i = 0; i < formElements.length; i++) {
    if(formElements[i].val == "" || (formElements[i].isNumber && isNaN(formElements[i].val)) {
        var err = "Please ";
        if(formElements[i].isNumber) {
            err += "insert " + formElements[i].name + ", must be numerical.";
        } else {
            err += "select " + formElements[i].name + ".";
        }
        alert(err);
    }
}

Note: I noticed a pattern in your code; for every element that required numerical input, it's error message used the verb "insert", and for every elemnt that required string/select input, it's error message used the verb "select". I used this pattern to auto-generate an error message.

Now, for setting up the info variable, all we have to do is iterate through the element array again but this time, as we are iterating, concatenate the name property of each object into the string, an '=', and then the value delimited by a &:

for(i = 0; i < formElements.length; i++) {
    info += formElements[i].name + "=" + formElements[i].val;
    if(i != formElements.length - 1) { // so we don't add a '&' to the end of the string
        info += "&";
    }
}

Putting that all together, your code would look like this:

function AjaxPost () {

    var xmlhttp;
    var url = "weight_p.php";

    var age = new FormElement("age", true);
    var height_ft = new FormElement("height_ft", true);
    var height_in = new FormElement("height_in", true);
    var weight = new FormElement("weight", true);
    var gender = new FormElement("gender", false);
    var activity = new FormElement("acitivity", false);

    // Validate all values entered
    for(var i = 0; i < formElements.length; i++) {
        if(formElements[i].val == "" || (formElements[i].isNumber && isNaN(formElements[i].val)) {
            var err = "Please ";
            if(formElements[i].isNumber) { // use verb "insert"
                err += "insert " + formElements[i].name + ", must be numerical.";
            } else { // use verb "select"
                err += "select " + formElements[i].name + ".";
            }
            alert(err);
        }
    }

    // These are all the values we are sending
    for(i = 0; i < formElements.length; i++) {
        info += formElements[i].name + "=" + formElements[i].val;
        if(i != formElements.length - 1) { // so we don't add a '&' to the end of the string
            info += "&";
        }
    }

    ... the rest is the same ...
}

Now, all you have to do when you add a new form element is create a new FormElement object and add it to the array.

If you encounter any bugs with this code, notify me.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.