Frage

Ich habe Probleme mit meinem Javascript. Es scheint seltsam wirken zu werden. Dies ist, was vor sich geht. Ich habe ein Formular, nachdem der Benutzer es vorträgt, nennt es eine Funktion (onsubmit Ereignis), um die übermittelten Daten zu überprüfen, wenn etwas schlecht oder wenn der Benutzername / E-Mail bereits in der Datenbank ist (unter Verwendung von Ajax für diesen Teil) es wird false zurück und zeigt Fehler mit DOM. Hier ist der Code unten. Was komisch daran ist, dass es nur funktioniert, wenn ich einen leeren Alarm verwenden ( ‚‘) Nachricht, ohne sie, es funktioniert einfach nicht. Danke für die Hilfe.

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

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;
    }

}
War es hilfreich?

Lösung

Die alert() hilft, weil das die Verarbeitung des restlichen Javascript in dieser Funktion (alles von den alert() bis auf den Boden) verzögert, genügend Zeit für die Anfrage AJAX verlassen abzuschließen. Der erste Buchstabe in AJAX steht für „asynchron“, was bedeutet, dass (standardmäßig) die Antwort kommen wird an „irgendwann in der Zukunft“, aber nicht sofort.

Ein Fix (die Sie sollten nicht implementieren) ist die Verarbeitung synchron zu machen (durch das dritte Argument von open() Ändern false zu sein), die weitere Bearbeitung des Skripts zu stoppen (und die gesamte Webseite ), bis die Anfrage zurückkehrt. Das ist schlecht, weil es effektiv den Web-Browser einfrieren, bis die Anforderung abgeschlossen ist.

Die richtige Lösung ist, den Code restrukturieren, so dass jede Verarbeitung, die auf dem Ergebnis des AJAX-Request hängt an die onreadystatechange Funktion geht, und kann nicht in der Hauptfunktion sein, die die AJAX-Anforderung initiiert.

Die Art und Weise dies in der Regel behandelt wird, ist Ihren DOM ändert Nur-Lese die Form (vor dem AJAX-Request gesendet wird) zu machen und eine Art „Verarbeitung“ -Meldung, dann in dem AJAX-Antwort-Handler anzuzeigen, ob alles in Ordnung ist (die Server reagierte richtig und Validierung erfolgreich war) Aufruf submit() auf dem Formular, da sonst die Form wriable wieder machen und alle Validierungsfehler angezeigt werden.

Andere Tipps

Das Problem ist, dass XMLHTTPRequest asynchron ist - die Anforderung im Hintergrund sendet und wartet nicht, es zu beenden

.

Die alert Anweisung bewirkt, dass der Code warten, bis der Benutzer auf OK klickt, in dem der Antrag beendet ist.

Sie müssen die onreadystatechange Ereignis verwenden, wie folgt aus:

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

Die Methode, die Sie zu dieser Eigenschaft zuweisen wird aufgerufen, nachdem die Antwort empfangen wird. (Und zu anderen Zeiten, weshalb Sie überprüfen müssen, dass readyState 4)

Du schickt die Anfrage asynchron , aus diesem Grunde:

xmlhttp.open(..., true);

Passing true als das dritte Argument zu open() bedeutet, dass der Code läuft weiter, bevor das Ergebnis kommt zurück.

Die alert() wird geben, dass asynchrone Anforderung Zeit abgeschlossen ist, bevor der nachfolgende Code ausgeführt wird.

Ich würde normalerweise empfehlen, die gesamten Code zu bewegen, die auf dem Ergebnis des Ajax-Aufrufs in den Rückruf abhängt, innerhalb dem:

if(xmlhttp.readyState == 4)

Block, aber in Ihrem Fall müssen Sie das Ergebnis des Aufrufs zu wissen, was Sie von Ihrer Validierungsfunktion zurückzukehren. In diesem Fall, Sie gehen einen synchronen Aufruf zu verwenden zu haben, von false zu open() vorbei. Dann wird Ihr nachfolgender Code nicht ausgeführt werden, bis die Antwort ist zurückgekommen.

Diese Jungs sind richtig, aber ich würde auch sicher sein, die Bool aus der Validierungsmethode zurückzukehren, um die Einreichung des Formulars wird abgebrochen, wenn das Formular nicht gültig ist.

Etwas entlang der Linien von:

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

...

</form>

Sie können auch immer false zurück von validateRegForm und haben die xmlhttp.onreadystatechange = function () das Formular abschicken, wenn sie gültig ist, oder auf andere Weise Ihre Fehlermeldung angezeigt.

Das ist, weil Ihr AJAX-Aufruf asynchron ist. Der Code folgende xmlhttp.send() wird sofort ausgeführt. Es muss nicht warten, bis Ihr Ajax-Aufruf zu beenden (es sei denn, Sie die Alarmbereitschaft versetzt).

Verschieben der gesamte Code nach dem Ajax-Aufruf an die Callback-Methode ausgeführt werden, um sicherzustellen, dass es ausgeführt wird, nachdem der Anruf beendet ist.

[Bearbeiten]. Abgesehen von dem Problem, denke ich AJAX einfach das Formular zu validieren und ermöglicht dann dem Benutzer die übliche Art und Weise ein wenig zu unterbreiten ungerade mir scheint

Können Sie die Validierung in zwei Teile unterteilen? Eine, die rein auf der Client-Seite getan werden kann, und die andere, die die serverseitige Validierung beinhaltet. Sie können sich ganz auf Server-Seite den zweiten Teil dazu bei einreichen und die Fehler zurück an den Client zurück.

Eine weitere Option ist die traditionelle einreichen ganz zu vermeiden. Da Sie die Ajax-Aufruf ohnehin tun, warum nicht tun Sie das Speichern / Bearbeiten / was auch immer in der sich Ajax-Aufruf wodurch die Notwendigkeit für eine einreichen? Beachten Sie aber, Sie werden immer noch die regelmäßige einreichen unterstützen müssen, wenn der Benutzer JavaScript deaktiviert hat.

Sie haben den dritten Parameter zu übergeben als falsch xmlhttp.open (), dann wird es funktionieren

Ich habe das gleiche Problem, wenn ich den Typen bin mit = „submit“, zum Beispiel:

<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

aber ich ändere es = "button" eingeben und es funktioniert.

Ich habe das gleiche Problem hat. Sobald ich den alert("") entfernen funktioniert es nicht. Habe ich es aus, und das ist der Deal.

In HTML, wenn Sie <button></button> verwenden Ihre Taste zu platzieren, wirkt der Browser unterschiedlich; wenn Sie darauf klicken, nachdem die Ereignishandler aufrufen, ist es die Seite neu geladen und das ist, warum Sie eine alert("") platzieren sollten nur nach dem Code der Seite aus neu zu laden.

zu verhindern

Sie können einfach verwenden <input type="button" value="something"> statt <button></button> von Neuladen der Seite, um den Browser zu verhindern.

Ich hatte das gleiche Problem und einfach hinzugefügt:

    <?php
    usleep(200000)// 2 seconds

?>

nach dem Javascript (die btw, einen Aufschub brachte jQuery 1.9.1 auf den Kopf

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top