web-dev-qa-db-fra.com

plugin jquery.validate - comment couper les valeurs avant la validation du formulaire

J'utilise l'excellent jquery.validation plugin de Jörn Zaefferer et je me demandais s'il existait un moyen facile de supprimer automatiquement les éléments de formulaire avant leur validation.

Voici un exemple simplifié mais pratique de formulaire qui valide une adresse électronique:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
           type="text/javascript"></script>
    <script src="http://ajax.Microsoft.com/ajax/jquery.validate/1.5.5/jquery.validate.js" 
           type="text/javascript"></script>
    <script type="text/javascript">
        $().ready(function() {
          $("#commentForm").validate({
            rules: {
                email: {
                    required: true,
                    email: true
                }
            }
          });
        });
    </script>
</head>
<body>

  <form class="cmxform" id="commentForm" method="get" action="">
     <label for="cemail">E-Mail:</label><input id="cemail" name="email"
      class="required email" />
     <input class="submit" type="submit" value="Submit"/>
  </form>

</body>
</html>

Le problème est que certains utilisateurs deviennent confus parce qu’ils ont accidentellement saisi des espaces dans leur adresse électronique, par exemple. "[email protected]". Et le formulaire ne sera pas envoyé et comportera un message d'erreur: "Veuillez entrer une adresse électronique valide.". Les utilisateurs non avertis ne savent pas comment repérer les espaces et peuvent simplement quitter le site plutôt que d'essayer de déterminer ce qu'ils ont mal fait.

Quoi qu'il en soit, j'espérais pouvoir enchaîner "jQuery.trim(value)" avant la validation afin que l'espace Soit éliminé et que l'erreur de validation ne se produise jamais?

Je pourrais utiliser addMethod pour créer ma propre fonction de validation de courrier électronique. Mais je suis sûr qu'il existe une solution plus élégante?

55
Tom

Je l'ai fait avec succès.

Au lieu de:

Email: { required: true, email: true }

J'ai fait ça:

Email: {
    required: {
        depends:function(){
            $(this).val($.trim($(this).val()));
            return true;
        }
    },
    email: true
}
81
MDP

Ce code fonctionne pour moi. Je ne l'ai pas beaucoup utilisé, il y a peut-être des bugs.

Il enveloppe chaque méthode et coupe le premier élément qui est value.

(function ($) {

    $.each($.validator.methods, function (key, value) {
        $.validator.methods[key] = function () {           
            if(arguments.length > 0) {
                arguments[0] = $.trim(arguments[0]);
            }

            return value.apply(this, arguments);
        };
    });
} (jQuery));

si vous utilisez select2 et la validation en même temps, je vous recommande de placer el.val($.trim(el.val())); dans un IF comme ceci: if(el.prop('type') != 'select-multiple'){el.val($.trim(el.val()));}. Ainsi, votre validation jquery se comportera comme prévu et vous permettra de sélectionner plusieurs éléments.

21
hwiechers

Puisque je veux ce comportement sur tous mes formulaires par défaut, j'ai décidé de modifier le fichier jquery.validate.js . J'ai appliqué la modification suivante à la méthode onfocusout:

Original:

onfocusout: function (element, event) {
    if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
        this.element(element);
    }
}

À:

onfocusout: function (element, event) {
    if (element.tagName === "TEXTAREA" || (element.tagName === "INPUT" && element.type !== "password")) {
        element.value = $.trim(element.value);
    }
    if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
        this.element(element);
    }
}

Je veux autoriser des espaces au début et à la fin du mot de passe.

autoTrim pourrait être ajouté en tant que propriété aux options.

12
tmorell

J'aime l'approche de xuser ( https://stackoverflow.com/a/10406573/80002 ), cependant, je n'aime pas jouer avec le code source du plugin.

Donc, je suggère de faire ceci à la place:

 function injectTrim(handler) {
  return function (element, event) {
    if (element.tagName === "TEXTAREA" || (element.tagName === "INPUT" 
                                       && element.type !== "password")) {
      element.value = $.trim(element.value);
    }
    return handler.call(this, element, event);
  };
 }


 $("form").validate({
    onfocusout: injectTrim($.validator.defaults.onfocusout)
 });
7
mark

Lors du téléchargement de validator.js, il existe un fichier appelé additional-methods.js qui contient la méthode "nowhitespace" et "lettersonly" qui supprimera tout espace blanc dans un champ.

rules: {
  user_name: {
    required: true,
    minlength: 3,
    nowhitespace: true
  }
}
6
jeremyzilar

Pour référence, jusqu'à ce que je trouve une solution plus élégante, j'utilise addMethod comme suit:

// Extend email validation method so that it ignores whitespace
jQuery.validator.addMethod("emailButAllowTrailingWhitespace", function(value, element) {
    return (this.optional(element) || jQuery.validator.methods.email.call(this, jQuery.trim(value), element));
}, "Please enter a valid email");

$().ready(function() {
    $("#commentForm").validate({
        rules: {
            cemail: {
                required: true,
                emailButAllowTrailingWhitespace: true
            }
        }
    });
});

Remarque: ceci ne supprime pas les espaces du champ, mais les ignore. Vous devez donc vous assurer que vous exécutez trim côté serveur avant de l'insérer dans la base de données.

4
Tom

Ajoutez une nouvelle méthode de validation jQuery requiredNotBlank. Appliquez ensuite cette fonction à vos éléments plutôt qu'à la fonction required par défaut. Cette solution ne modifie pas le code source du validateur d'origine, ne modifie pas non plus la fonction required par défaut, ni ne modifie directement la valeur de l'élément.

// jQuery Validator method for required not blank.
$.validator.addMethod('requiredNotBlank', function(value, element) {
    return $.validator.methods.required.call(this, $.trim(value), element);
}, $.validator.messages.required);

// ...
$('#requiredNotBlankField').rules('add', 'requiredNotBlank');
3
sevencardz

C'est ce qui fonctionne pour moi:

$(':input').change(function() {
    $(this).val($(this).val().trim());
});
3
user3830900

Tiré la regex du validateur JQuery. Il suffit de remplacer leur validation de courrier électronique.

$.validator.addMethod("email", function(value, element) {
value = value.trim();
return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
}, "Please enter a valid email.");
3
RyanCodes

Ne pourriez-vous pas lier le recadrage à un événement de flou? Quelque chose comme...

 $ ("# cemail"). blur (function () {
 $ (this) .val (jQuery.trim ($ (this) .val ()); 
}); 
2
Psytronic

J'ai constaté que la majorité d'entre eux ne correspond pas tout à fait à ce qu'il faut.

L'utilisation de ce qui suit se déclenche uniquement lors du changement de formulaire plutôt que lorsque vous appuyez sur une touche, ce qui vous permet de toujours vérifier la course de touche pour le reste de la validation.

Ce n'est pas aussi bien que de l'inclure dans le plugin, mais c'est un compromis acceptable.

$('body').on 'change', 'form input[type=text], form input[type=email]',  ->
    $(@).val $.trim($(@).val())
2
lededje

À partir du plugin jQuery Validation version 1.15, une fonction normalisation est prise en charge. Le normalisateur peut transformer la valeur d'un élément avant la validation. 

Notez que le résultat du normalisateur n'est utilisé que pour la validation. Si vous souhaitez mettre à jour la valeur de l'élément, vous devez le faire explicitement.

$("#form").validate({
    rules: {
        email: {
            required: true,
            email: true,
            // Optionally disable validation on every key press
            onkeyup: false,
            normalizer: function(value) {
                // Update the value of the element
                this.value = $.trim(value);
                // Use the trimmed value for validation
                return this.value;
            }
        }
    }
});
1
Craig Wohlfeil

Dans la validation JQuery, vous trouverez le code ci-dessous:

required: function( value, element, param ) {

        // Check if dependency is met
        if ( !this.depend( param, element ) ) {
            return "dependency-mismatch";
        }
        if ( element.nodeName.toLowerCase() === "select" ) {

            // Could be an array for select-multiple or a string, both are fine this way
            var val = $( element ).val();
            return val && val.length > 0;
        }
        if ( this.checkable( element ) ) {
            return this.getLength( value, element ) > 0;
        }
        return value.length > 0;
    }

Changez la valeur.length en $ .trim (valeur) .length

1
Amul

Vous pouvez exécuter le code avant que le formulaire ne soit vérifié comme ceci:

var origCheckForm = $.validator.prototype.checkForm;
$.validator.prototype.checkForm = function() {
    $(this.currentForm).find('.CodeMirror').each(function() {
        if(this.CodeMirror && this.CodeMirror.save) {
            this.CodeMirror.save();
        }
    });

    return origCheckForm.apply(this, arguments);
};

Je l'ai utilisé pour sauvegarder toutes mes instances CodeMirror dans leurs texareas correspondantes. Vous pouvez l'utiliser pour réduire les valeurs si vous le souhaitez.

0
mpen

Pourquoi ne pas faire ça?

La validation a lieu après l'événement keyup. Sur keyup, remplacez la valeur textbox par sa valeur ajustée (ou utilisez une expression rationnelle pour supprimer tout espace):

$("#user_name").on("keyup", function(){
    $("#user_name").val($.trim($("#user_name").val()));
});
0
Adrian P.