7
votes

JavaScript et Ajax, ne fonctionne que lors de l'utilisation d'alerte ()

J'ai des problèmes avec mon javascript. Il semble agir étrangement. C'est ce qui se passe. J'ai une forme, une fois que l'utilisateur l'a soumise, il appelle une fonction (ONSUBMIT EVENT) pour vérifier les données soumises, si quelque chose de mauvais ou si le nom d'utilisateur / e-mail est déjà dans la base de données (à l'aide de Ajax pour cette partie). et afficher des erreurs utilisant DOM. Voici le code ci-dessous. Ce qui est bizarre à ce sujet, c'est que cela ne fonctionne que lorsque j'utilise un message d'alerte vide (''), sans cela, cela 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;
    }

}


2 commentaires

Si vous suggérerait de jeter un coup d'œil à un cadre JavaScript comme JQuery, cela rend la vie tellement meilleure;)


Je déteste être le porteur de mauvaises nouvelles, mais votre JavaScript semble être bloqué en 2003.


10 Réponses :


2
votes

Vous envoyez la demande asynchrone forte>, à cause de cette suivante: xxx pré>

passe true code> comme troisième argument sur Open () Code> signifie que le code continuera à fonctionner avant que le résultat revienne. p>

L'alerte () code> donne cette date de demande asynchrone à compléter avant la suite Code exécute. p>

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

if(xmlhttp.readyState == 4)


1 commentaires

Je pense que vous avez transmettre le 3ème paramètre comme faux pour le rendre synchrone.



0
votes

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

Déplacez tout le code à exécuter après l'appel AJAX à la méthode de rappel pour vous assurer qu'il est exécuté après la fin de l'appel.

[modifier]: Mis à part le problème, je pense utiliser Ajax juste pour valider le formulaire, puis permettre à l'utilisateur de soumettre la manière habituelle de moi.

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

Une autre option consiste à éviter complètement la soumission traditionnelle. Depuis que vous faites l'appel Ajax quand même, pourquoi ne faites-vous pas la sauvegarde / édition / quel que soit l'appel AJAX enlever la nécessité d'une soumission? N'oubliez pas que vous devrez toujours prendre en charge la soumission régulière si l'utilisateur a désactivé JavaScript.


1 commentaires

Eh bien, la seule partie que j'utilise ajax pour est le nom d'utilisateur de contrôle et la disponibilité par courrier électronique de la DB.



0
votes

Ces gars-là ont raison mais je serais également sûr de renvoyer le bool de la méthode de validation afin que la soumission du formulaire soit annulée si le formulaire n'est pas valide.

quelque chose sur les lignes de: < PRE> XXX

Vous pouvez également toujours retourner faux de validateegformForm et avoir la fonction xmlhttp.onreadyStatechange = fonction () soumettre le formulaire s'il est valide s'il est valide, ou affichant votre message d'erreur.


2 commentaires

Merci pour la suggestion David, mais j'aurais dû mentionner que je l'ai comme un retour dans l'événement Onsubmit.


En tant que Sidenote, cela peut être un conseil utile, mais n'est entièrement lié à la question à la main



3
votes

Le problème est que xmlhttprequest est asynchrone - il envoie la demande en arrière-plan et n'attend pas qu'il finit.

L'instruction alerte provoque une attente du code jusqu'à ce que l'utilisateur clique sur OK, au cours de laquelle la demande se termine.

Vous devez utiliser l'événement onreadyStatechange , comme celui-ci: xxx

la méthode Vous attaquerez à cette propriété sera appelé après la réponse de la réponse. (Et à d'autres moments, c'est pourquoi vous devez vérifier que ReadyStat est 4)


0 commentaires

11
votes

L'alerte () aide car cela retarde le traitement du reste JavaScript dans cette fonction (tout de l'alerte () vers le bas), laissant suffisamment de temps pour la demande Ajax à compléter. La première lettre d'Ajax signifie "asynchrone", ce qui signifie que (par défaut) la réponse entrera à "un point à l'avenir" mais pas immédiatement.

Un correctif (que vous devriez pas Implément) est de faire le traitement synchrone (en modifiant le troisième argument de ouvert () pour être faux ) qui cessera de traitement ultérieur de votre script (et de toute la page Web) jusqu'à ce que la requête revienne. C'est mauvais car il gèlera efficacement le navigateur Web jusqu'à ce que la requête se termine.

Le correctif approprié consiste à restructurer votre code de sorte que tout traitement dépend du résultat de la requête AJAX se situe à la fonction onreadyStatechange et ne peut pas être dans la fonction principale qui initie le Demande Ajax.

La manière dont cela est généralement traitée consiste à modifier votre DOM (avant que la demande AJAX soit envoyée) pour formuler le formulaire à readonner et afficher une sorte de message "Traitement", puis dans le gestionnaire de réponse AJAX, si tout va bien (le Le serveur a répondu correctement et la validation a été réussi) appelez Soumettre () sur le formulaire, sinon, apportez le formulaire brouillé et affichez les erreurs de validation.


0 commentaires

0
votes

Vous devez passer le troisième paramètre sur xmlhttp.open () comme false, alors cela fonctionnera bien


2 commentaires

Bien que cela fonctionne, ce n'est pas la solution idéale car elle raccroche le navigateur pendant la durée de l'appel.


Quand j'ai essayé ça, ça n'a pas fonctionné, pas même avec l'alerte ().



-1
votes

J'ai eu le même problème. Une fois que je supprimai l'alerte ("") ça ne fonctionne pas. Je l'ai compris et c'est la transaction.

en HTML, lorsque vous utilisez 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 une alerte ("") juste après votre code pour empêcher la page de rechargement.

Vous pouvez simplement utiliser " quelque chose "> au lieu de pour empêcher le navigateur de recharger le navigateur page.


0 commentaires

-2
votes

J'ai eu le même problème et j'ai simplement ajouté:
    <?php
    usleep(200000)// 2 seconds


0 commentaires

0
votes

J'avais le même problème lorsque j'utilisais le type = "Soumettre", par exemple: xxx

mais je le change de type = " "Et ça marche.


0 commentaires

0
votes
<button onclick="AddComment(); return false;">Comment</button>

0 commentaires