Question

Je ne parviens pas à mon javascript. Il semble agir bizarrement. C'est ce qui se passe. J'ai une forme, après que l'utilisateur soumet, il appelle une fonction (événement onsubmit) pour vérifier les données fournies, si quelque chose de mauvais ou si le nom d'utilisateur / email est déjà dans la base de données (en utilisant ajax pour cette partie), il retournera faux et afficher les erreurs en utilisant DOM. Voici le code ci-dessous. Ce qui est bizarre à ce sujet, est qu'il ne fonctionne que lorsque j'utilise un message d'alerte vide ( « »), sans elle, il ne fonctionne tout simplement pas. Merci pour l'aide.

//////////////////////////////////////

function httpRequest() {
    var xmlhttp;

    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        // code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        alert("Your browser does not support XMLHTTP!");
    }

    return xmlhttp;
}

function validateRegForm(reg) {

    var isValidForm = true;
    var warningIcon = "";//for later in case we want to use an icon next to warning msg

    with(reg) {


        var regFormDiv = document.getElementById("registration_form");

        //Check if dynamic div exist, if so, remove it
        if(document.getElementById('disp_errors') != null) {
            var dispErrorsDiv = document.getElementById('disp_errors');
            document.getElementById('reg_form').removeChild(dispErrorsDiv);
        }           

        //Dynamically create new 'div'
        var errorDiv = document.createElement('div');
        errorDiv.setAttribute('id','disp_errors');
        errorDiv.setAttribute('style','background-color:pink;border:1px solid red;color:red;padding:10px;');
        document.getElementById('reg_form').insertBefore(errorDiv,regFormDiv);




        var xmlhttp = httpRequest();
        var available = new Array();
        xmlhttp.onreadystatechange = function() {
            if(xmlhttp.readyState == 4)
            {   
                var response = xmlhttp.responseText;
                if(response != "") {

                    //Return values
                    var newValue = response.split("|");
                    available[0] = newValue[0]; 
                    available[1] = newValue[1]; 
                }
            }
        }

        xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+u_username.value+"&email="+u_email.value+"",true);
        xmlhttp.send(null);


        alert(' '); ////////////WITHOUT THIS, IT DOESN'T WORK. Why?

        if(available[1] == "taken") {
            errorDiv.innerHTML += warningIcon+'Username is already taken!<br />';
            isValidForm = false;
        } else if(u_username.value.length < 4){
            errorDiv.innerHTML += warningIcon+'Username must be more than 4 characters long!<br />';
            isValidForm = false;
        } else if(u_username.value.length > 35) {
            errorDiv.innerHTML += warningIcon+'Username must be less than 34 characters long!<br />';
            isValidForm = false;
        }


        if(available[0] == "taken") {
            errorDiv.innerHTML += warningIcon+'Email address entered is already in use!<br />';
            isValidForm = false;
        } else if(u_email.value == ""){
            errorDiv.innerHTML += warningIcon+'Email address is required!<br />';
            isValidForm = false;
        } else {
            //Determine if email entered is valid
            var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
            if (!filter.test(u_email.value)) {
                errorDiv.innerHTML += warningIcon+'Email entered is invalid!<br />';
                u_email.value = "";
                isValidForm = false;
            }
        }


        if(u_fname.value == ""){
            errorDiv.innerHTML = warningIcon+'Your first name is required!<br />';
            isValidForm = false;
        }

        if(u_lname.value == ""){
            errorDiv.innerHTML += warningIcon+'Your last name is required!<br />';
            isValidForm = false;
        }



        if(u_password.value.length < 4){
            errorDiv.innerHTML += warningIcon+'Password must be more than 4 characters long!<br />';
            isValidForm = false;
        } else if(u_password.value.length > 35) {
            errorDiv.innerHTML += warningIcon+'Password must be less than 34 characters long!<br />';
            isValidForm = false;
        } else if (u_password.value != u_password2.value) {
            errorDiv.innerHTML += warningIcon+'Password and re-typed password don\'t match!<br />';
            isValidForm = false;
        }


        if(u_squestion.value == ""){
            errorDiv.innerHTML += warningIcon+'A security question is required!<br />';
            isValidForm = false;
        }

        if(u_sanswer.value == ""){
            errorDiv.innerHTML += warningIcon+'A security answer is required!<br />';
            isValidForm = false;
        }

        if(u_address.value == ""){
            errorDiv.innerHTML += warningIcon+'Address is required!<br />';
            isValidForm = false;
        }

        if(u_city.value == ""){
            errorDiv.innerHTML += warningIcon+'City is required!<br />';
            isValidForm = false;
        }

        if(u_state.value == ""){
            errorDiv.innerHTML += warningIcon+'State is required!<br />';
            isValidForm = false;
        }

        if(u_zip.value == ""){
            errorDiv.innerHTML += warningIcon+'Zip code is required!<br />';
            isValidForm = false;
        }

        if(u_phone.value == ""){
            errorDiv.innerHTML += warningIcon+'Phone number is required!<br />';
            isValidForm = false;
        }

        if(isValidForm == false)
            window.scroll(0,0);

        return isValidForm;
    }

}
Était-ce utile?

La solution

Le alert() aide parce que retarde le traitement du javascript restant dans cette fonction (tout du alert() vers le bas), ce qui laisse suffisamment de temps pour la demande AJAX pour terminer. La première lettre en AJAX signifie « asynchrone » qui signifie que (par défaut), la réponse viendra à « un moment donné dans l'avenir », mais pas immédiatement.

Une solution (que vous devriez pas mettre en œuvre) est de rendre le synchrone de traitement (en modifiant le troisième argument de open() être false) qui arrête le traitement ultérieur de votre script (et la page web entière ) jusqu'à ce que le retour de demande. Ceci est mauvais car il effectivement geler le navigateur Web jusqu'à ce que la demande complète.

Le correctif approprié est de restructurer votre code afin que tout traitement qui dépend du résultat de la requête AJAX va dans la fonction onreadystatechange, et ne peut pas être dans la fonction principale qui initie la requête AJAX.

La façon dont cela est généralement traité est de modifier votre DOM (avant la demande AJAX est envoyé) pour faire le formulaire en lecture seule et afficher une sorte de message « de traitement », puis dans le gestionnaire de réponse AJAX, si tout va bien (le serveur a répondu correctement et validation a réussi) submit() d'appel sur la forme, sinon faire à nouveau la forme wriable et afficher les erreurs de validation.

Autres conseils

Le problème est que XMLHttpRequest est asynchrone - il envoie la requête en arrière-plan et ne l'attend pas pour terminer

.

L'instruction alert provoque le code d'attendre jusqu'à ce que l'utilisateur clique sur OK, au cours de laquelle la demande se termine.

Vous devez utiliser l'événement onreadystatechange, comme ceci:

xmlhttp.onreadystatechange = function() {
    if(xmlhttp.readyState==4) {
        // Do things
    }
};

La méthode que vous attribuez à cette propriété sera appelée après la réponse est reçue. (Et à d'autres moments, ce qui est la raison pour laquelle vous devez vérifier que readyState est 4)

Vous envoyez la demande de manière asynchrone , à cause de cela:

xmlhttp.open(..., true);

En passant true comme troisième argument à open() signifie que le code continue de fonctionner avant que le résultat revient.

Le alert() donne que le temps de requête asynchrone pour terminer avant le code suivante fonctionne.

Je recommande normalement déplacer tout le code qui dépend du résultat de l'appel AJAX dans le rappel, dans le:

if(xmlhttp.readyState == 4)

bloc, mais dans votre cas vous avez besoin du résultat de l'appel de savoir quoi revenir de votre fonction de validation. Dans ce cas, vous allez devoir utiliser un appel synchrone, en passant false à open(). Ensuite, votre code subséquent ne fonctionnera pas jusqu'à ce que la réponse est revenue.

Ces gars-là ont raison, mais je voudrais aussi être sûr de retourner le bool de la méthode de validation de sorte que la soumission du formulaire est annulée si le formulaire est pas valide.

Quelque chose le long des lignes de:

<form onsubmit="return IsValid();">

...

</form>

Vous pouvez aussi toujours revenir faux de validateRegForm et ont la xmlhttp.onreadystatechange = function () soumettre le formulaire si elle est valide, ou autrement afficher votre message d'erreur.

C'est parce que votre appel AJAX est asynchrone. Le code xmlhttp.send() suivant est exécuté immédiatement. Il n'attend pas votre appel ajax à la fin (sauf si vous mettez l'alerte).

Déplacer tout le code à exécuter après l'appel ajax à la méthode de rappel pour vous assurer qu'il est exécuté une fois l'appel terminé.

[Modifier]:. Mis à part le problème, je pense en utilisant AJAX juste pour valider le formulaire et permettant à l'utilisateur de soumettre la manière habituelle me semble un peu bizarre à

Pouvez-vous diviser la validation en 2 parties? Qui peut être fait uniquement sur le côté client et l'autre qui implique la validation côté serveur. Vous pouvez faire la deuxième partie complètement sur côté serveur à soumettre et renvoyer les erreurs de retour au client.

Une autre option est d'éviter la traditionnelle soumettre tout à fait. Puisque vous faites l'appel ajax de toute façon, pourquoi ne pas faire la sauvegarde / modifier / whatever dans le ajax lui-même appeler en supprimant la nécessité de soumettre? Gardez à l'esprit cependant, vous aurez toujours besoin de soutenir la régulière soumettre si l'utilisateur a désactivé javascript.

Vous devez passer le troisième paramètre à xmlhttp.open () comme faux, alors il fonctionnera très bien

Je faisais le même problème quand j'utilisais le type = « submit », par exemple:

<button type="submit" class="btn btn-default" name="btn-login" id="btn-login" onclick="submitForm()">
  <span class="glyphicon glyphicon-log-in"></span> &nbsp; Sign In

mais je change à type = "button" et cela fonctionne.

J'ai eu le même problème. Une fois que je l'enlève alert("") il ne fonctionne pas. J'ai tout compris et c'est l'affaire.

En HTML, lorsque vous utilisez <button></button> pour placer votre bouton, le navigateur agit différemment; lorsque vous cliquez dessus, après avoir appelé le gestionnaire d'événements, il recharge la page et c'est pourquoi vous devez placer un alert("") juste après votre code pour empêcher la page de rechargement.

Vous pouvez simplement utiliser <input type="button" value="something"> au lieu de <button></button> pour empêcher le navigateur de recharger la page.

J'ai eu le même problème et simplement ajouté:

    <?php
    usleep(200000)// 2 seconds

?>

après le javascript (qui d'ailleurs, a entraîné le report de jQuery 1.9.1 à la tête

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top