jquery.проверить плагин - как обрезать значения перед проверкой формы


Я использую отлично jquery.плагин проверки Jörn Zaefferer и мне было интересно, есть ли простой способ автоматически обрезать элементы формы до их проверки?

ниже приведен сокращенный, но рабочий пример формы, которая проверяет адрес электронной почты:

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

проблема в том, что некоторые пользователи путаются, потому что они случайно вводят некоторые пробелы в свой адрес электронной почты, например "test@test.com ". И форма не отправить и сообщение об ошибке: "пожалуйста, введите действительный адрес электронной почты.". Нетехнические пользователи не знают, как определить пробелы и могут просто выйти из сайта, а не пытаться выяснить, что они сделали неправильно.

в любом случае, я надеялся, что смогу приковать "jQuery.trim(value) " перед проверкой так что пробелы удаляются, и ошибка проверки никогда не возникает?

я мог бы использовать addMethod построить свою собственную функцию проверки электронной почты. Но я уверен, что есть еще элегантное решение?

15 54

15 ответов:

Я сделал это с успехом.

вместо:

Email: { required: true, email: true }

Я сделал так:

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

этот код работает для меня. Я не использовал его много, так что могут быть ошибки.

он обертывает каждый метод и обрезает первый элемент, который является значением.

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

Если вы используете select2 и проверку одновременно, я рекомендую поставить el.val($.trim(el.val())); внутри если так: if(el.prop('type') != 'select-multiple'){el.val($.trim(el.val()));}. Таким образом, ваша проверка jquery будет вести себя так, как ожидалось, и это позволит вам выбрать несколько элементов.

Так как я хочу, чтобы это поведение на всех моих формах по умолчанию я решил изменить jquery.утверждать.js файл. Я применил следующее изменение к методу onfocusout:

Оригинал:

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

Я хочу разрешить пробелы в начале и конце пароля.

autoTrim может быть добавлен в качестве свойства опций.

Мне нравится подход xuser (https://stackoverflow.com/a/10406573/80002), однако, мне не нравится возиться с исходным кодом плагина.

Итак, я предлагаю сделать это вместо:

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

при загрузке валидатор.js, есть файл под названием additional-methods.js, который содержит метод "nowhitespace" и "lettersonly", который будет удалять любое пустое пространство в поле.

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

Для справки, пока я не найду более элегантное решение, я использую addMethod следующим образом:

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

Примечание: это на самом деле не удаляет пробелы из поля, он только игнорирует его. Поэтому вам нужно убедиться, что вы выполняете trim на стороне сервера перед вставкой в БД.

вытащил регулярное выражение из валидатора jquery. Просто переопределите их проверку электронной почты.

$.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.");

Это то, что работает для меня:

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

Не могли бы вы привязать обрезку к событию размытия? Что-то вроде этого...

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

Я обнаружил, что большинство из них не совсем то, что нужно.

использование следующих только срабатывает при изменении формы, а не при нажатии клавиши вниз, позволяя вам по-прежнему проверять ход клавиши для остальной части проверки.

Это не так аккуратно, как включая его в плагин, но это приемлемый компромисс.

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

Добавить новый метод проверки jQuery requiredNotBlank. Затем примените эту функцию к своим элементам, а не по умолчанию

в jQuery validation вы найдете следующий код:

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

изменить значение.длина до $.обрезка (значение).длина

вы можете запустить код перед проверкой формы следующим образом:

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

я использовал его, чтобы сохранить все мои экземпляры CodeMirror обратно в соответствующие texareas. Вы можете использовать его для обрезки значений, если хотите.

почему бы не сделать это?

проверка происходит после события keyup. В keyup замените значение текстового поля его обрезанным значением (или используйте регулярное выражение для удаления любого пространства):

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

начиная с версии плагина проверки jQuery 1.15 a функции нормализатор поддерживается. Нормализатор может преобразовать значение элемента перед проверкой.

обратите внимание, что результат нормализатора используется только для проверки. Если вы хотите обновить значение элемента, вы должны сделать это явно.

$("#form").validate({
    rules: {
        email: {
            required: true,
            email: true,
            normalizer: function(value) {
                // Update the value of the element
                this.value = $.trim(value);
                // Use the trimmed value for validation
                return this.value;
            }
        }
    }
});