it-roy-ru.com

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

Я использую отличный плагин jquery.validation от 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>

Проблема в том, что некоторые пользователи запутываются, потому что они случайно вводят пробелы в свой адрес электронной почты, например, "[email protected]". И форма не будет отправлена ​​и имеет сообщение об ошибке: «Пожалуйста, введите действительный адрес электронной почты». Нетехнические пользователи не знают, как распознать пробелы, и могут просто покинуть сайт, а не пытаться понять, что они сделали неправильно.

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

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

55
Tom

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

Вместо:

Email: { required: true, email: true }

Я сделал это:

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

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

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

(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, например, так: if(el.prop('type') != 'select-multiple'){el.val($.trim(el.val()));}. Таким образом, ваша проверка JQuery будет вести себя как положено, и это позволит вам выбрать несколько элементов.

21
hwiechers

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

Оригинал:

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

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

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

12
tmorell

Мне нравится подход 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)
 });
7
mark

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

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

Для справки, пока я не найду более элегантное решение, я использую 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 на стороне сервера, прежде чем вставлять в БД.

4
Tom

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

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

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

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

Вытащил регулярное выражение из валидатора 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.");
3
RyanCodes

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

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

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

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

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

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

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

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

$("#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

В проверке jquery вы найдете следующий код:

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

Измените значение value.length на $ .trim (значение) .length

1
Amul

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

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. Вы можете использовать его для обрезки значений, если хотите.

0
mpen

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

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

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