Pregunta

Tengo problemas con mi javascript. Parece estar actuando de manera extraña. Esto es lo que está pasando. Tengo una forma, después de que el usuario envía él, llama a una función (evento onsubmit) para verificar los datos presentados, si algo malo o si el nombre de usuario / correo electrónico ya está en la base de datos (usando ajax para esta parte) que va a devolver false y mostrar errores usando DOM. Aquí está el código de abajo. Lo raro de ello, es que sólo funciona cuando se utiliza una alerta vacía ( '') del mensaje, sin ella, simplemente no funciona. Gracias por la ayuda.

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

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

}
¿Fue útil?

Solución

El alert() ayuda debido a que retrasa el procesamiento del Javascript que queda en esa función (todo, desde la alert() hasta la parte inferior), dejando tiempo suficiente para que la petición AJAX para completar. La primera letra de AJAX es sinónimo de "asíncrono", que significa que (por defecto) la respuesta vendrá en en "algún momento en el futuro", pero no inmediatamente.

Una solución (que debe no en práctica) es hacer que el sincrónica procesamiento (cambiando el tercer argumento de open() ser false) que se detendrá el procesamiento posterior de la secuencia de comandos (y toda la página web ) hasta que la solicitud de devolución. Esto es malo porque va a congelar efectivamente el navegador web hasta que la solicitud completa.

La solución correcta es la reestructuración de su código para que cualquier proceso que depende del resultado de la petición AJAX entra a la función onreadystatechange, y no puede estar en la función principal que inicia la petición AJAX.

La forma en que esto generalmente se maneja es modificar el DOM (antes de la petición AJAX se envía) para hacer la forma de sólo lectura y mostrar algún tipo de mensaje "procesamiento", a continuación, en el manejador de la respuesta AJAX, si todo está bien (la servidor respondió correctamente y de validación se ha realizado correctamente) llamada submit() en el formulario, de lo contrario hacer la forma wriable de nuevo y mostrar algún error de validación.

Otros consejos

El problema es que XMLHTTPRequest es asíncrona - se envía la solicitud en el fondo y no espera a que termine

.

La declaración alert hace que el código que esperar hasta que el usuario hace clic en OK, durante el cual la solicitud termina.

Es necesario utilizar el evento onreadystatechange, como esto:

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

El método se asigna a esta propiedad se llamará después de recibir la respuesta. (Y en otras ocasiones, por lo que es necesario comprobar que es readyState 4)

Se va a enviar la solicitud asíncrona , debido a esto:

xmlhttp.open(..., true);

Al pasar true como tercer argumento a open() significa que el código seguirá funcionando antes de que el resultado se vuelve.

El alert() está dando ese momento solicitud asincrónica para completar antes de que acabe el código siguiente.

Me gustaría normalmente recomiendo mover todo el código que depende del resultado de la llamada AJAX en la devolución de llamada, incluida en:

if(xmlhttp.readyState == 4)

bloque, pero en su caso se necesita el resultado de la llamada para saber qué regrese de su función de validación. En ese caso, vas a tener que utilizar una llamada sincrónica, pasando a false open(). A continuación, el código subsiguiente no se ejecutará hasta que la respuesta ha regresado.

Estos chicos tienen razón pero también serían Asegúrese de devolver la bool del método de validación por lo que la presentación del formulario se cancela si el formulario no es válido.

Algo a lo largo de las líneas de:

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

...

</form>

También podría volver siempre falsa de validateRegForm y tienen la xmlhttp.onreadystatechange = function () enviar el formulario si es válido, o no mostrar el mensaje de error.

Esto es debido a que su llamada AJAX es asíncrona. El siguiente código xmlhttp.send() se ejecuta inmediatamente. No espere a que su llamada AJAX para terminar (a menos que poner la alerta).

Mover todo el código que se ejecuta después de la llamada AJAX al método de devolución de llamada para asegurarse de que se ejecuta después de terminar la llamada.

[Editar]:. Aparte del problema, creo que el uso de AJAX sólo para validar el formulario y luego permitiendo que el usuario envíe la forma habitual parece un poco extraño para mí

Se puede dividir la validación en 2 partes? Uno que puede hacerse únicamente en el lado del cliente y la otra que consiste en la validación del lado del servidor. Usted puede hacer la segunda parte completamente en el lado del servidor al enviar y devolver los errores de nuevo a cliente.

Otra opción es evitar el tradicional someter por completo. Desde que está haciendo la llamada ajax de todos modos, ¿por qué no hacer el saque de arco / editar / lo que sea en el propio ajax llaman la eliminación de la necesidad de un presente? Tenga en cuenta, sin embargo, todavía se necesita para apoyar someter el regular si el usuario tiene JavaScript desactivado.

Usted tiene que pasar el tercer parámetro a Xmlhttp.open () como falso, entonces todo funcionará bien

I estaba teniendo el mismo problema cuando estaba usando el type = "submit", por ejemplo:

<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

pero lo cambio de tipo "botón" = y funciona.

He tenido el mismo problema. Una vez que se quita la alert("") no funciona. Lo he descubierto y que es el reparto.

En HTML, cuando se utiliza <button></button> para colocar el botón, el navegador actúa de forma diferente; cuando se hace clic en él, después de llamar al controlador de eventos, se vuelven a cargar la página y es por eso que usted debe colocar una alert("") justo después de su código para evitar que la página de recarga.

Usted puede simplemente utilizar <input type="button" value="something"> en lugar de <button></button> a impedir que el navegador recargar la página.

Yo tenía el mismo problema y simplemente añadí:

    <?php
    usleep(200000)// 2 seconds

?>

después de la javascript (que por cierto, implicaba diferir jQuery 1.9.1 a la cabeza

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top