Плагин Проверки jQuery: Вызовите функцию errorPlacement когда onfocusout, keyup и щелчок

Я использую плагин проверки jQuery и хочу использовать функцию errorPlacement, чтобы добавить сообщения об ошибках к полевому атрибуту заголовка и отобразить просто ✘ рядом с полем.

Это работает отлично, когда форма отправлена с кнопкой отправки, но когда любое из следующих событий инициировано: - onfocusout - щелчок - onkeyup

Проверки проверки осуществляются, но это пропускает функцию errorPlacement и добавляет полное сообщение об ошибке после поля, как поведение по умолчанию.

Я использую следующий код:

$("#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"
});
10
задан th3hamburgler 8 March 2010 в 11:02
поделиться

2 ответа

Ваша проблема в том, что плагин вызывает функцию errorPlacement только один раз для каждого проверенного элемента. Namly, когда впервые создается метка ошибки для элемента. После этого плагин просто повторно использует уже существующую метку и просто заменяет html внутри (или скрывает метку ошибки, если элемент теперь действителен). Вот почему ваш крестик удаляется, и отображается фактическое сообщение об ошибке.

Просто чтобы убедиться, что поток плагина понятен. Элемент

  1. (метки ошибки еще нет) Элемент
  2. в какой-то момент проверяется.
  3. плагин создает метку ошибки и вызывает errorPlacement функцию
  4. элемент «крест» (сообщение об ошибке в заголовке)
  5. Элемент получает фокус, и вы что-то меняете
  6. плагин повторно проверяет элемент
  7. Видит, что метка ошибки уже создана (и размещена)
  8. плагин просто вызывает label.html (message) вместо удаления старого label and reading it

Итак, вы видите, что ваша проблема - это своего рода оптимизация, которую плагин выполняет, чтобы сохранить некоторые ненужные вставки / удаления меток ошибок. Что тоже имеет смысл.

Вы можете проверить, что я сказал, посмотрев на исходный код плагина проверки

jquery.validate.js v1.6 проверьте в функции showLabel строки 617–625 для соответствующих частей.


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

Что-то вроде

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

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

17
ответ дан 3 December 2019 в 20:41
поделиться

Спасибо jitter ,

Я покопался и обнаружил ту же проблему.

Мне удалось заставить его работать, «взломав» функцию showLabel в jquery.validation.js. Это некрасиво, но работает.

Переопределение параметра функции showErrors избавит меня от необходимости изменять код плагина, поэтому я посмотрю.

Вот код, который я использовал для метода 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);
        }
1
ответ дан 3 December 2019 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: