Как использовать Twitter Bootstrap popovers для уведомлений о проверке jQuery?
Я могу сделать всплывающие окна появляются с помощью bootstrap достаточно легко, и я также могу делать проверки с помощью стандартного проверка jQuery плагин или jQuery validation engine, но я не могу понять, как кормить одного в другое.
Я думаю, что мне нужен какой-то крючок, который вызывается валидатором, когда он хочет отобразить уведомление, дать ему закрытие, которое передает сообщение и целевой элемент в popover. Это выглядит так своего рода инъекция зависимости.
все хорошо в теории, но я просто не могу понять, где этот крючок, или даже если он существует в любом механизме проверки. Они оба, похоже, намерены взять на себя ответственность за отображение уведомлений со всеми видами сложных вариантов размещения, оберток, стилей, когда все, что мне нужно, - это тип(ы) ошибки (мне даже не обязательно нужен текст сообщения) и элемент, к которому он относится. Я нашел крючки для всей формы, а не для отдельного человека уведомления.
Я предпочитаю системы проверки, которые используют классы для определения правил, так как они хорошо работают с динамически созданными формами.
У кого-нибудь есть решение или идея получше?
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); } });
Он действительно не использует 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"); }); } });
получится что-то вроде этого:
Проверьте 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) сделает трюк.
Это также добавляет в некоторых 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"); } }