2010-03-08 8 views
10

Sto utilizzando il plug-in di convalida jquery e voglio utilizzare la funzione errorPlacement per aggiungere messaggi di errore all'attributo title del campo e visualizzare solo un ✘ accanto al campo.jQuery Plugin di convalida: Richiama la funzione errorPlacement quando onfocusout, keyup e fai clic su

questo funziona grande quando il modulo viene inviato con il pulsante di invio, ma quando uno dei seguenti eventi sono attivati: - onfocusout - clicca - onkeyup

I controlli di convalida vengono eseguiti, ma salta la funzione errorPlacement e aggiunge il messaggio di errore completo dopo il campo, come il comportamento predefinito.

Sto usando il seguente codice:

$("#send-mail").validate({ 
    debug: true, 
    // set this class to error-labels to indicate valid fields 
    success: function(label) { 
     // set text as tick 
     label.html("✔").addClass("valid"); 
    }, 
    // the errorPlacement has to take the table layout into account 
    errorPlacement: function(error, element) { 
     console.log("errorPlacement called for "+element.attr("name")+" field"); 
     // check for blank/success error 
     if(error.text() == "") 
     { 
      // remove field title/error message from element 
      element.attr("title", ""); 
      console.log("error check passed"); 
     } 
     else 
     { 
      // get error message 
      var message = error.text(); 

      // set as element title 
      element.attr("title", message); 

      // clear error html and add cross glyph 
      error.html("✘"); 

      console.log("error check failed: "+message); 
     } 
     // add error label after form element 
     error.insertAfter(element); 
    }, 
    ignoreTitle: true, 
    errorClass: "invalid" 
}); 

risposta

16

Il tuo problema è che il plugin chiama solo la funzione errorPlacement una volta per ogni elemento che viene convalidato. Vale a dire quando viene creata per la prima volta l'etichetta dell'errore per l'elemento. Successivamente il plug-in riutilizza l'etichetta già presente e sostituisce semplicemente l'html all'interno (o nasconde l'etichetta dell'errore se l'elemento è ora valido). Ecco perché la croce viene rimossa e viene visualizzato il messaggio di errore effettivo.

Giusto per assicurarsi che il flusso del plugin sia chiaro.

  1. elemento (ancora senza errorlabel)
  2. elemento viene convalidato a un certo punto
  3. plug crea un'etichetta di errore e chiama errorPlacement funzione
  4. elemento "croce" (messaggio di errore nel titolo)
  5. elemento ottiene focus e si modifica qualcosa
  6. plug-in convalida elemento
  7. Visualizza l'etichetta di errore già creata (e posizionata)
  8. plug chiama semplicemente label.html(message) invece di rimuovere vecchia etichetta e readding si

Così si vede il problema è un tipo di ottimizzazione del plugin fa per salvare alcuni inutili inserti/rimuove di etichette di errore. Anche questo ha un senso.

È possibile controllare quello che ho detto, cercando in validazione-plugin-sorgente

jquery.validate.js v1.6 check-in funzione showLabel linee 617-625 per i pezzi rilevanti.


Una possibile soluzione potrebbe essere quella di fornire un ulteriore showErrors callback personalizzato che risolve il problema con forza bruta.

Qualcosa sulla falsariga di

$("#send-mail").validate({ 
... 
    showErrors: function(errorMap, errorList) { 
     for (var i = 0; errorList[i]; i++) { 
      var element = this.errorList[i].element; 
      //solves the problem with brute force 
      //remove existing error label and thus force plugin to recreate it 
      //recreation == call to errorplacement function 
      this.errorsFor(element).remove(); 
     } 
     this.defaultShowErrors(); 
    } 
... 
}); 

Forse c'è una soluzione più pulita a questo, ma questo dovrebbe farlo e dare il tempo di indagare su una soluzione migliore.

+0

aiutato ........ :) –

1

Grazie jitter,

ho fatto un po 'scavare intorno ed ho trovato lo stesso problema.

Sono riuscito a farlo funzionare "hacking" la funzione showLabel in jquery.validation.js. Non è carino ma funziona.

Ignorare l'opzione di funzione showErrors mi impedirà di dover modificare il codice del plugin in modo da dare un'occhiata.

Ecco il codice che ho usato per il metodo showLabel:

 showLabel: function(element, message) { 

      // look for existing error message 
      var label = this.errorsFor(element); 
      // existing error exist? 
      if (label.length) { 
       // refresh error/success class 
       label.removeClass().addClass(this.settings.errorClass); 

       // check if we have a generated label, replace the message then 
       label.attr("generated"); 

       // is message empty? 
       if(!message) 
       { 
        // add tick glyph 
        label.html("✔"); 

        // wipe element title 
        $(element).attr('title', message) 
       } 
       else 
       { 
        // clear error html and add cross glyph 
        label.html("✘"); 

        // update element title 
        $(element).attr('title', message) 
       } 

       // && label.html(message); 
      } 
      else { 
       // create label 
       label = $("<" + this.settings.errorElement + "/>") 
        .attr({"for": this.idOrName(element), generated: true}) 
        .addClass(this.settings.errorClass) 
        .html(message || ""); 
       if (this.settings.wrapper) { 
        // make sure the element is visible, even in IE 
        // actually showing the wrapped element is handled elsewhere 
        label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); 
       } 
       if (!this.labelContainer.append(label).length) 
        this.settings.errorPlacement 
         ? this.settings.errorPlacement(label, $(element)) 
         : label.insertAfter(element); 
      } 
      if (!message && this.settings.success) { 
       label.text(""); 
       typeof this.settings.success == "string" 
        ? label.addClass(this.settings.success) 
        : this.settings.success(label); 
      } 
      this.toShow = this.toShow.add(label); 
     } 
Problemi correlati