0
votes

I have got a validation script which validates my form first, if everything is okay it will return true (obviously PHP checks will be done as well after).

I have also got a JavaScript function which uploads the image and displays a progress bar, this is where things seem to be going wrong, the form is still submitting whilst the image is being uploaded, if it's uploading it should return false.

Form onsubmit call:

<form action="php/submitMessage.php" onsubmit="return !!(validation(this) && submitFile('image','reviewUpload'));" method="post" id="submitMessage">

Validation Script:

function validation(form) {
    var inputs = form.elements;
    var errors = Array();

    for(var i=0;i<inputs.length;i++) {
        if (inputs[i].getAttribute("rules") != null && inputs[i].getAttribute("rules") != "") {
            var re = new RegExp(inputs[i].getAttribute("rules"));
            var OK = re.test(inputs[i].value);

            if (!OK) {
                inputs[i].style.backgroundColor = "#e39d9d";
                errors.push(false);
            } else {
                inputs[i].style.backgroundColor = "#6dcd6b";
                errors.push(true);
            }
        }
    }

    //Check array for any errors
    if (errors.indexOf(false) == -1) {
        return true;
    } else {
        return false;
    }
}

This is my image upload script, people are not required to add an image, so I have made it return true IF NO image has been selected.

function submitFile(fileId,buttonId) {
    //Has a file been selected
    if (doc(file).value != "") {
        //Generate a new form
        var f = document.createElement("form");
        f.setAttribute("method", "POST");
        f.setAttribute("enctype", "multipart/form-data");

        //Create FormData Object
        var formData = new FormData(f);

        //Append file
        formData.append("image", doc(file).files[0], "image.jpg");

        var xhr = new XMLHttpRequest();
        xhr.open("POST", "php/uploadImage.php", true);
        xhr.onload = function(e) {
            if (xhr.status == 200) {
                if (xhr.responseText == "true") {
                    return true;
                } else if (xhr.responseText == "false") {
                    return false;
                }
            } else {
                console.log("error!");
                console.log("Error " + xhr.status + " occurred when trying to upload your file");
            }
        };

        //Progress
        xhr.upload.onprogress = function(e) {
            if (e.lengthComputable) {
                var currentPercentage = Math.round(e.loaded / e.total * 100)-1;
                document.getElementById(buttonId).innerHTML = "UPLOAD IMAGE " + currentPercentage + "%";
                document.getElementById(buttonId).style.backgroundSize = (currentPercentage+1) + "% 100%";
                if (currentPercentage==99) {
                    document.getElementById(buttonId).innerHTML = "Processing image";
                }
            }
        };

        //Send data
        xhr.send(formData);
    } else {
        return true;
    }
}

Edit:

function handleSubmit() {
    //Validate the form
    var valid = validation(this);
    var formElement = this;

    //Check if validation passes
    if (valid == true) {
        //code here...
    } else {
        return false;
    }
}

Even when validation() returns false the form is still submitting.

Form opening:

<form action="php/submitMessage.php" method="post" id="messageForm">
1
How are you submitting your form? Is there a submit button which is clicked? If so, you can change to a simple button, fire a function that validate form, upload the image, the fire the submit on form.Ricardo Pontual
You can write single submit handler to do both validation check and image upload to get a better control of situation. Coming to your question, since image upload is asynchronous call submit functionality will not wait for completion of upload. You should handle success callback and submit after upload success and a separate submit handler will help in it.guleria
@RicardoPontual Ah thats a good ideaMartyn Ball
@guleria submit that as an answer, as that is perfect, didn't think of doing that.Martyn Ball

1 Answers

1
votes

Writing this as answer as said by @Martin Ball

You can write single submit handler to do both validation check and image upload to get a better control of situation. Coming to your question, since image upload is asynchronous call submit functionality will not wait for completion of upload. You should handle success callback and submit after upload success and a separate submit handler will help in it. e.g.

function handleSubmit () {
    // validate your form
    validation(this);
    var xhr = new XMLHttpRequest();
    // code to build XMLHttpRequest

    var formElement = this;
    xhr.onload = function (e) {
        // code to handle success

        // on success
        // submit form
        formElement.submit();
    };
}

function validation () {
    // logic to validate form
}

// attach submit to handler
var formElement = document.querySelector('submitMessage');
formElement.addEventListener('submit', handleSubmit);

Edit In case you want to stop form from submitting you need to tell the event to stop doing the default action i.e. preventDefault.

see this jsbin for demo and code sample.

TLDR;

function handleSubmit (ev) {
    var isValid = validation(this);
    if(!valid) {
        ev.preventDefault();
        return false;
    }
    // further handling of submit action.
}