Как использовать Twitter Bootstrap popovers для уведомлений о проверке jQuery?


Я могу сделать всплывающие окна появляются с помощью bootstrap достаточно легко, и я также могу делать проверки с помощью стандартного проверка jQuery плагин или jQuery validation engine, но я не могу понять, как кормить одного в другое.

Я думаю, что мне нужен какой-то крючок, который вызывается валидатором, когда он хочет отобразить уведомление, дать ему закрытие, которое передает сообщение и целевой элемент в popover. Это выглядит так своего рода инъекция зависимости.

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

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

У кого-нибудь есть решение или идея получше?

16 84

16 ответов:

посмотри highlight и showErrorsпараметры валидатора jQuery, это позволит вам подключить свои собственные пользовательские ошибки, которые запускают всплывающие окна Bootstrap.

это практический пример:

$('form').validate({
    errorClass:'error',
    validClass:'success',
    errorElement:'span',
    highlight: function (element, errorClass, validClass) { 
        $(element).parents("div[class='clearfix']").addClass(errorClass).removeClass(validClass); 
    }, 
    unhighlight: function (element, errorClass, validClass) { 
        $(element).parents(".error").removeClass(errorClass).addClass(validClass); 
    }
});

enter image description here

Он действительно не использует bootstrap popovers, но он выглядит очень красиво и легко достижим.

обновление

Итак, для проверки popover вы можете использовать этот код:

$("form").validate({
  rules : {
    test : {
      minlength: 3 ,
      required: true
    }
  },
  showErrors: function(errorMap, errorList) {
    $.each(this.successList, function(index, value) {
      return $(value).popover("hide");
    });
    return $.each(errorList, function(index, value) {
      var _popover;
      _popover = $(value.element).popover({
        trigger: "manual",
        placement: "top",
        content: value.message,
        template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>"
      });
      // Bootstrap 3.x :      
      //_popover.data("bs.popover").options.content = value.message;
      // Bootstrap 2.x :
      _popover.data("popover").options.content = value.message;
      return $(value.element).popover("show");
    });
  }
});

получится что-то вроде этого:

enter image description here

Проверьте jsFiddle.

Крис Fulstow был прав, но он все-таки взял меня некоторое время, так что вот полный код:

это показывает всплывающее сообщение об ошибке и скрывает метки ошибок по умолчанию:

$('#login').validate({
  highlight: function(element, errClass) {
    $(element).popover('show');
  },
  unhighlight: function(element, errClass) {
    $(element).popover('hide');
  },
  errorPlacement: function(err, element) {
    err.hide();
  }
}).form();

это устанавливает popover. Единственное, что вам нужно от этого триггер: 'руководство'

$('#password').popover({
  placement: 'below',
  offset: 20,
  trigger: 'manual'
});

атрибуты заголовка и содержимого, переданные в popover, не работали, поэтому я указал их в строке ввода #password с data-content= 'минимум 5 символов' и data-original-title= 'неверный пароль'. Вам также нужно rel= 'popover' в вашей форме.

это работает, но поповер мерцает при снятии выбора. Есть идеи, как это исправить?

вот продолжение отличного предложения от Варуна Сингха, которое предотвращает проблему " мерцания "проверки, постоянно пытаясь" показать", хотя всплывающее окно уже присутствует. Я просто добавил сообщение об ошибке различными государствами для захвата элементов, показывающие ошибок и не. Работает как шарм!

var errorStates = [];

$('#LoginForm').validate({
    errorClass:'error',
    validClass:'success',
    errorElement:'span',
    highlight: function (element, errorClass) {
        if($.inArray(element, errorStates) == -1){
            errorStates[errorStates.length] = element;
            $(element).popover('show');
        }
    }, 
    unhighlight: function (element, errorClass, validClass) {
        if($.inArray(element, errorStates) != -1){
            this.errorStates = $.grep(errorStates, function(value) {
              return value != errorStates;
            });
            $(element).popover('hide');
        }
    },
    errorPlacement: function(err, element) {
        err.hide();
    }
});

$('#Login_unique_identifier').popover({
    placement: 'right',
    offset: 20,
    trigger: 'manual'
});

$('#Login_password').popover({
    placement: 'right',
    offset: 20,
    trigger: 'manual'
});

Это расширение jQuery для плагина проверки jQuery (протестировано с версией 1.9.0) сделает трюк.

https://github.com/tonycoco/rails_template/blob/master/files/assets/javascripts/jquery.validate.bootstrap.js

Это также добавляет в некоторых Rails-esk сообщения об ошибках.

Я предпочитаю изменить CSS bootstrap. Просто добавлены классы jQuery validate в нужном месте. поле-проверка-ошибка и ввод-проверка-ошибка

    form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline, .field-validation-error {
  color: #b94a48;
}
form .clearfix.error input, form .clearfix.error textarea, .input-validation-error {
  color: #b94a48;
  border-color: #ee5f5b;
}
form .clearfix.error input:focus, form .clearfix.error textarea:focus, .input-validation-error:focus {
  border-color: #e9322d;
  -webkit-box-shadow: 0 0 6px #f8b9b7;
  -moz-box-shadow: 0 0 6px #f8b9b7;
  box-shadow: 0 0 6px #f8b9b7;
}

вот как я сделал это с Bootstrap 2.x и jQuery проверяют 1.9

$('#form-register').validate({ errorElement: 'span', errorClass:'help-inline', highlight:    function (element, errorClass) {
        $(element).parent().parent().addClass('error');
    }, unhighlight: function (element, errorClass) {
        $(element).parent().parent().removeClass('error');
    }});

пожалуйста, взгляните на следующее:
- https://gist.github.com/3030983
Я думаю, что это самый простой из всех.

EDIT

код ссылки:

$('form').validate({
    rules: {
        numero: {
            required: true
        },
        descricao: {
            minlength: 3,
            email: true,
            required: true
        }
    },

    showErrors: function (errorMap, errorList) {

        $.each(this.successList, function (index, value) {
            $(value).popover('hide');
        });


        $.each(errorList, function (index, value) {

            console.log(value.message);

            var _popover = $(value.element).popover({
                trigger: 'manual',
                placement: 'top',
                content: value.message,
                template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
            });

            _popover.data('popover').options.content = value.message;

            $(value.element).popover('show');

        });

    }

});

большое спасибо за головы! Вот моя версия для Bootstrap, но с подсказками. На мой взгляд это более элегантно, чем эклеры. Я знаю, что вопрос был для popovers, поэтому, пожалуйста,не голосуйте по этой причине. Может быть, кому-то это понравится. Я люблю, когда я ищу что-то, и я нашел новые идеи на Stackoverflow. Примечание: никакая разметка на форме не требуется.

    $('#LoginForm').validate({
        rules: {
            password: {
                required: true,
                minlength: 6
            },

            email_address: {
                required: true,
                email: true
            }
        },
        messages: {
            password: {
                required: "Password is required",
                minlength: "Minimum length is 6 characters"
            },
            email_address: {
                required: "Email address is required",
                email: "Email address is not valid"
            }
        },  
        submitHandler: function(form) {
            form.submit();
        },

        showErrors: function (errorMap, errorList) {

            $.each(this.successList, function (index, value) {
                $('#'+value.id+'').tooltip('destroy');
            });


            $.each(errorList, function (index, value) {

                $('#'+value.element.id+'').attr('title',value.message).tooltip({
                    placement: 'bottom',
                    trigger: 'manual',
                    delay: { show: 500, hide: 5000 }
                }).tooltip('show');

            });

        }

    }); 

вот как я это сделал. Но это включает в себя внесение 2 изменений в сценарий проверки (я получил код для bootstrap 1.4 здесь, а затем изменил его - http://mihirchitnis.net/2012/01/customizing-error-messages-using-jquery-validate-plugin-for-twitter-bootstrap/)

мой вызов для проверки:

    $("#loginForm").validate({
  errorClass: "control-group error",
  validClass: "control-group success",
  errorElement: "span", // class='help-inline'
  highlight: function(element, errorClass, validClass) {
    if (element.type === 'radio') {
        this.findByName(element.name).parent("div").parent("div").removeClass(validClass).addClass(errorClass);
    } else {
        $(element).parent("div").parent("div").removeClass(validClass).addClass(errorClass);
    }
  },
  unhighlight: function(element, errorClass, validClass) {
    if (element.type === 'radio') {
        this.findByName(element.name).parent("div").parent("div").removeClass(errorClass).addClass(validClass);
    } else {
        $(element).parent("div").parent("div").removeClass(errorClass).addClass(validClass);
    }
  }
});

тогда вам нужно изменить 2 вещи в jquery.утверждать.js
1. применить это исправление - https://github.com/bsrykt/jquery-validation/commit/6c3f53ee00d8862bd4ee89bb627de5a53a7ed20a
2. После строки 647 (в функции showLabel создайте часть метки) после строки .addClass(this.settings.errorClass) добавить строку: .addClass("help-inline")
Кто-то может найти способ применить второе исправление в функции validate, но я не нашел способ, так как showLabel вызывается после выделения.

это то, что я положил в мою проверку, чтобы соответствовать рекомендациям Twitter Bootstrap. Сообщение об ошибке проверки в <span class=help-inline> и мы хотим выделить внешний контейнер как error или success:

errorClass:'help-inline',
errorElement:'span',
highlight: function (element, errorClass, validClass) {
$(element).parents("div.clearfix").addClass('error').removeClass('success');
},
unhighlight: function (element, errorClass, validClass) {
$(element).parents(".error").removeClass('error').addClass('success');
}

вот обновление до отличный ответ Кенни Мейера выше. Было несколько проблем, которые мешали ему работать для меня, которые я рассмотрел в этом фрагменте:

showErrors: function (errorMap, errorList) {
        $.each(this.successList, function (index, element) {
            return $(element).popover("destroy");
        });

        $.each(errorList, function (index, error) {
            var ele = $(error.element); //Instead of referencing the popover directly, I use the element that is the target for the popover

            ele.popover({
                    trigger: "manual",
                    placement: "top",
                    content: function(){ //use a function to assign the error message to content
                        return error.message
                    },
                    template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
            });

            //bs.popover must be used, not just popover
            ele.data("bs.popover").options.content = error.message;

            return $(error.element).popover("show");
        });
    }

Не уверен, что это имеет отношение к обсуждению, потому что оригинальный плакат попросил крючки, чтобы показать/скрыть Bootstrap popovers.

Я искал простой проверки и popovers не имеет значения. А похожие статьи и первым в результатах поиска google уже был отмечен дубликат этого вопроса. Поэтому имело смысл упомянуть этот превосходный @Reactiveraven's jqValidation JS, метко называемый jqBootstrapValidation, который хорошо сочетается с Twitter Bootstrap. Установка занимает всего несколько минут. Скачать здесь.

надеюсь, что это добавляет ценность.

tl; dr избегайте необходимости перечислять явные поповеры, используя хэш-карту для хранения идентификаторов элементов и создания поповеров на лету (подходы Джеффри Гилберта и Кенни Мейера).

вот мое мнение, которое исправляет проблему мерцания, упомянутую другими, но в отличие от ответа @ Jeffrey Gilbert, не использует список (errorStates), но скорее использует ошибки карта. Хэш-карты стандарта. Мне кажется, я где-то читал, что каждая проблема в CS можно решить с помощью хэш-карты :)

var err_map = new Object();     // <--- n.b.
$("form#set_draws").validate({
  rules: {
    myinput: { required: true, number: true },
  },
  showErrors: function(errorMap, errorList) {
    $.each(this.successList, function(index, value) {
      if (value.id in err_map)
      {
        var k = err_map[value.id];
        delete err_map[value.id]; // so validation can transition between valid/invalid states
        k.popover("hide");
      }
    });
    return $.each(errorList, function(index, value) {
      var element = $(value.element);
      if( ! (value.element.id in err_map) ) {
        var _popover = element.popover({
          trigger: "manual",
                 placement: "top",
                 content: value.message,
                 template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>"
        });
        _popover.data("popover").options.content = value.message;
          err_map[value.element.id] = _popover;
        return err_map[value.element.id].popover("show");
      }
    });
  }
});

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

проверьте это:https://github.com/mingliangfeng/jquery.validate.bootstrap.popover

Он показывает, как использовать Bootstrap popover css, а не JS. Всплывающее окно метода JS вызовет проблему с миганием.

Если вы используете приведенный выше код Кенни Мейера для всплывающих окон, помните, что правила, которые проверяют содержимое поля, но не требуются, например, допустимый URL-адрес, заставят всплывающее окно не исчезать при очистке поля. См. ниже onkeyup для решения. Если у кого-то есть лучшее решение, пожалуйста, напишите.

onkeyup: function(element, event) {
            if($(element).valid())  {
                return $(element).popover("hide");
            }
        }