Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery.validate plugin - how to trim values before form validation

I'm using the excellent jquery.validation plugin by Jörn Zaefferer and I was wondering whether there's a easy way to automatically trim form elements before they are validated?

The following is a cut down but working example of a form which validates a email address:

<!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>

The problem is that some users are getting confused because they accidently enter some whitespace in their email address, e.g. "[email protected] ". And the form won't submit and has a error message: "Please enter a valid email address.". Non-techy users don't know how to spot whitespace and may just quit the site rather than try to work out what they've done wrong.

Anyway, I was hoping I could chain "jQuery.trim(value)" before the validation so the whitespace is removed and the validation error never occurs?

I could use addMethod to build my own email validation function. But I'm sure there's a more elegant solution?

like image 550
Tom Avatar asked Dec 01 '09 16:12

Tom


4 Answers

I did this with success.

Instead of:

Email: { required: true, email: true }

I did this:

Email: {
    required: {
        depends:function(){
            $(this).val($.trim($(this).val()));
            return true;
        }
    },
    email: true
}
like image 134
MDP Avatar answered Nov 17 '22 06:11

MDP


This code works for me. I haven't used it much so there may be bugs.

It wraps each method and trims the first element which is 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));

if you're using select2 and validation at the same time, I recommend to put el.val($.trim(el.val())); inside an IF like this: if(el.prop('type') != 'select-multiple'){el.val($.trim(el.val()));}. That way, your jquery validation will behave as expected, and it will let you select multiple items.

like image 42
hwiechers Avatar answered Nov 17 '22 08:11

hwiechers


Since I want this behavior on all my forms by default I decided to modify the jquery.validate.js file. I applied the following change to onfocusout method:

Original:

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

To:

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

I do want to allow spaces at the begging and end of password.

autoTrim could be added as a property to options.

like image 28
tmorell Avatar answered Nov 17 '22 08:11

tmorell


I like the approach by xuser (https://stackoverflow.com/a/10406573/80002), however, I do not like messing with the plugin source code.

So, I suggest doing this instead:

 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)
 });
like image 14
mark Avatar answered Nov 17 '22 08:11

mark