jQuery validator e una regola personalizzata che utilizza AJAX

Ho letto la tua risposta per quanto riguarda jQuery validatore in cui si struttura un metodo per controllare un nome utente contro un valore in un database.

Ive ha provato l’implementazione di questo metodo, ma non importa ciò che viene restituito dal file PHP ricevo sempre il messaggio che il nome utente è già stato preso.

Qui è ths metodo personalizzato…

$.validator.addMethod("uniqueUserName", function(value, element) {
  $.ajax({
      type: "POST",
       url: "php/get_save_status.php",
      data: "checkUsername="+value,
      dataType:"html",
   success: function(msg)
   {
      //if the user exists, it returns a string "true"
      if(msg == "true")
         return false;  //already exists
      return true;      //username is free to use
   }
 })}, "Username is Already Taken");

E qui è la convalida del codice…

username: {
    required: true,
    uniqueUserName: true
},

C’è un modo specifico che devo restituire il messaggio da php.

Grazie

Un

 

4 Replies
  1. 60

    Si sta facendo una richiesta AJAX, ergo: la convalida è già finito di lavorare quando il custom validator che restituisce true o false.

    È necessario lavorare con async. Vedi anche questo post: Come posso ottenere jQuery per eseguire un sincrono, piuttosto che asincrona, richiesta Ajax?

    Qualcosa di simile:

    function myValidator() {
       var isSuccess = false;
    
       $.ajax({ url: "", 
                data: {}, 
                async: false, 
                success: 
                    function(msg) { isSuccess = msg === "true" ? true : false }
              });
        return isSuccess;
    }

    Attenzione:

    Come jQuery 1.8, l’uso di async: false con jqXHR ($.Differite) è
    sconsigliato; è necessario utilizzare il successo/errore/completare le opzioni di richiamata
    al posto dei corrispondenti metodi di jqXHR oggetto come
    jqXHR.fatto() o deprecato jqXHR.il successo().

    • Grazie. La tua risposta lavorato una delizia!
    • potete per favore dare la tua lavorato esempio di codice
    • Per farlo funzionare ho dovuto cambiare msg===”true” msg===true (Firefox). Grazie per la soluzione per la via!
    • Per chiunque inciampo su questo in futuro, async è stato deprecato. Vedere Tim risposta qui sotto.
    • Questo congelare la pagina, se la convalida del server richiede tempo.
    • Basato sul deprezzamento del async: false, penso che questo non dovrebbe essere la risposta corretta

  2. 62

    Per chiunque altro che inciampa su questo, convalidare supporta “in remoto”, metodo, che non può esistere nel 2010:

    https://jqueryvalidation.org/remote-method/

    $("#myform").validate({
      rules: {
        email: {
          required: true,
          email: true,
          remote: {
            url: "check-email.php",
            type: "post",
            data: {
              username: function() {
                return $("#username").val();
              }
            }
          }
        }
      }
    });
    • È questa async richiesta o richiesta di sincronizzazione?
    • questo è un asincrono convalida
    • potrebbe, per favore, fammi sapere come ritardare questa richiesta remota?
  3. 11

    Mi ci sono voluti per sempre per capire come ottenere un jsonified stringa contenente il valore di un elemento della pagina in remoto richiesta – questo è il risultato di una combinazione di molte ore, e cercando molti risultati di ricerca.

    Punti chiave:

    1. async:false è stato deprecato,
    2. la chiamata di funzione destro dopo remote: è la chiave per la creazione di dati stringa con il valore dell’elemento. Tentando di accedere a un valore di corrente dalla forma dopo data: è stato restituito un valore vuoto per il campo con dataType impostare come json.

          $("#EmailAddress").rules("add", {
          required: true,
          remote: function () { //the function allows the creation of the data string 
                                //outside of the remote call itself, which would not 
                                //return a current value from the form.
              var emailData = "{'address':'" + 
                              $('#SignupForm :input[id$="EmailAddress"]').val() + 
                              "'}";
              var r = {
                  url: "foobar.aspx/IsEmailAvailable",
                  type: "post",
                  dataType: "json",
                  contentType: "application/json; charset=utf-8",
                  cache: false,
                  data: emailData,
                  dataFilter: function(response) {
                      this.email_run = true; //fix for race condition with next button
                      return isAvailable(data); //return true or false
                  }
              };
              return r;
          },
          messages: {
              remote: "* Email in use"
          }
      });

    .Pagina ASPX:

    <input id="EmailAddress" required name="Email" type="email" placeholder="Email Address*" runat="server"/>

    C# Codice Di Dietro:

    [WebMethod]
        public static object IsEmailAvailable(string address){...}

    Formattazione dell’oggetto response:

    function isAvailable(data) {
        var response = JSON.parse(getJsonObject(data));
        return (response.isAvailable === "True") ? true : false;
    };
    
    //transform response string to a JavaScript Object()
    //http://encosia.com/never-worry-about-asp-net-ajaxs-d-again/
    function getJsonObject(data) {
        var msg = eval('(' + data + ')');
        if (msg.hasOwnProperty('d'))
            return msg.d;
        else
            return msg;
    };
    • con riguardo all’istruzione – 1. async:false has been deprecated,.. Sì, MA è ancora permesso di utilizzare la giusta richiamata/gestore, ad esempio ( complete: , success: , error: ) piuttosto che una Promessa metodo come .then o .done… Vedere il seguente riferimento qui ==> bugs.jquery.com/ticket/11013#comment:40
  4. 0

    Ecco la mia “vecchia scuola” hack…

    Al di sotto di una funzione di utilità che consente l’utilizzo di “asincrono” validazioni con “jquery.validate.js” biblioteca. Questa funzione crea un ritardo tra l’utente battiture, altrimenti la funzione di validazione “validFunc” sarà chiamato “all time”, che non è molto performativo, in alcune circostanze, e particolarmente problematico per le funzioni che svolgono le convalide su “serverside”/”back-end” (chiamate ajax in fondo). In questo modo il “validFunc” funzione di validazione viene chiamato solo quando l’utente smette di digitare per un certo periodo di tempo, che consente anche di un “realtime” convalida ("onkeyup": true su jqv impostazioni), come si verifica mentre l’utente sta digitando.

    IMPORTANTE: Convalide che prevedono l’uso del “jqvAsyncValid” la funzione deve essere sempre gli ultimi, per evitare conflitti con gli altri a causa di asincronia.

    {
        [...]
        "rules": {
            "field_name": {
                "required": true,
                "maxlength": 12,
                "minlength": 4,
    
                //NOTE: Validation involving the use of the "jqvAsyncValid" function. By Questor
                "my_custom_ajax_validation": true
    
            },
        [...]
    }

    DI RISPOSTA CODICE:

    //NOTE: Adds the custom validation "my_custom_ajax_validation". By Questor
    $.validator.addMethod("my_custom_ajax_validation", function (value, element) {
        return jqvAsyncValid(element, "my_custom_ajax_validation", myValidationFunc, this);
    }, "My error message!");
    
    //NOTE: My validation function. By Questor
    function myValidationFunc(domElement) {
        if (someFuncWithAjaxCall(domElement.value) == "ALL_RIGHT!") {
            return true;
        } else {
            return false;
        }
    }
    
    //NOTE: Global "json" variable that stores the "status" ("isValid") and cycle control
    //("toCtrl") of asynchronously validated elements using the "jqvAsyncValid" function.
    //By Questor
    var jqvAsyncVState = {};
    
    //NOTE: A utility function that allows the use of asynchronous validations with
    //"jquery.validate.js". This function creates a delay between one user keystroke and
    //another otherwise the validation function "validFunc" will be called "all time"
    //which is not very performative in some circumstances and especially problematic
    //for functions that perform validations on the serverside/backend (ajax calls basically).
    //In this way the "validFunc" validation function is only called when the user stops
    //typing for a certain period of time, which also allows a "realtime" validation
    //as it occurs while the user is typing. By Questor
    //[Ref .: https://jqueryvalidation.org/]
    //. domElement - DOM element informed by jqv in the "addMethod" for the anonymous
    //function;
    //. asyncRuleNm - Validation name added via "addMethod";
    //. validFunc - Function that will do the validation. Must have the signature
    //"funcName(domElement)" returning "true" for valid and "false" for not;
    //. jQValidInst - Instance of the current jqv within "addMethod". It is usually
    //denoted by "this";
    //. toInMsecs - "Timeout" in "milliseconds". If not informed the default will be
    //1500 milliseconds. Be careful not to use a very short timeout especially in
    //"ajax" calls so as not to overload the serverside/backend.
    //Eg.: `return jqvAsyncValid(element, "my_custom_ajax_validation", myValidationFunc, this);`.
    function jqvAsyncValid(domElement, asyncRuleNm, validFunc, jQValidInst, toInMsecs) {
        if (typeof toInMsecs === "undefined" || toInMsecs === "") {
            toInMsecs = 1500;
        }
        var domEKey = jQValidInst.currentForm.id + domElement.name;
    
        //NOTE: The validation messages need to be "displayed" and "hidden" manually
        //as they are displayed asynchronously. By Questor
        function errMsgHandler() {
            if (jqvAsyncVState[domEKey]["isValid"]) {
    
                //NOTE: If the current error message displayed on the element was that
                //set in the rule added via "addMethod" then it should be removed since
                //the element is valid. By Questor
                //[Ref.: https://stackoverflow.com/a/11652922/3223785 ,
                //https://stackoverflow.com/a/11952571/3223785 ]
                if (jQValidInst.errorMap[domElement.name] == $.validator.messages[asyncRuleNm]) {
                    var iMsgNow = {};
                    iMsgNow[domElement.name] = "";
                    jQValidInst.showErrors(iMsgNow);
                }
    
            } else {
                var iMsgNow = {};
    
                //NOTE: If the element is invalid, get the message set by "addMethod"
                //for current rule in "$.validator.messages" and show it. By Questor
                iMsgNow[domElement.name] = $.validator.messages[asyncRuleNm];
                jQValidInst.showErrors(iMsgNow);
    
            }
        }
        if (!jqvAsyncVState.hasOwnProperty(domEKey)) {
    
            //NOTE: Set the global json variable "jqvAsyncVState" the control attributes
            //for the element to be asynchronously validated if it has not already been
            //set. The key "domEKey" is formed by the "id" of the "form" that contains
            //the element and the element's "name". By Questor
            jqvAsyncVState[domEKey] = {
                "toCtrl": null,
                "isValid": undefined
            };
    
        }
        var useOnKeyup = true;
    
        //NOTE: The "onblur" event is required for "first validation" that only occurs
        //in a "blur" event - this is inherent to jqv - and for situations where the
        //user types very fast and triggers "tab" and the event "onkeyup" can not deal
        //with it. By Questor
        domElement.onblur = function (e) {
            jqvAsyncVState[domEKey]["isValid"] = validFunc(domElement);
            errMsgHandler();
            useOnKeyup = false;
        }
        if (useOnKeyup) {
    
            //NOTE: The strategy with the event "onkeyup" below was created to create
            //a "delay" between a "keystroke" and another one otherwise the validation
            //function "validFunc" will be called "all time" which is not very performative
            //in some circumstances and especially problematic for functions that perform
            //serverside/backend validations (ajax calls basically). In this way the
            //"validFunc" validation function is only called when the user stops typing
            //for a certain period of time ("toInMsecs"). By Questor
            domElement.onkeyup = function (e) {
    
                //NOTE: Clear the "toCtrl" if it has already been set. This will
                //prevent the previous task from executing if it has been less than
                //"toInMsecs". By Questor
                clearTimeout(jqvAsyncVState[domEKey]["toCtrl"]);
    
                //NOTE: Make a new "toCtrl" set to go off in "toInMsecs" ms. By Questor
                jqvAsyncVState[domEKey]["toCtrl"] = setTimeout(function () {
                    jqvAsyncVState[domEKey]["isValid"] = validFunc(domElement);
                    errMsgHandler();
                }, toInMsecs);
            };
        }
        return jqvAsyncVState[domEKey]["isValid"];
    }

Lascia un commento