Як використовувати поповери Twitter Bootstrap для сповіщень про перевірку jQuery?


84

Я можу зробити так, щоб поповери з'являлися за допомогою bootstrap досить легко, а також я можу робити перевірки, використовуючи стандартний плагін перевірки jQuery або механізм перевірки jQuery , але я не можу зрозуміти, як подавати одне в інше.

Я думаю, що мені потрібно, це якийсь хук, який викликається валідатором, коли він хоче відобразити сповіщення, дати йому закриття, яке передає повідомлення та цільовий елемент поповеру. Це здається своєрідною ін'єкцією залежності.

Теоретично все добре, але я просто не можу зрозуміти, де знаходиться цей гачок, або навіть якщо такий існує в будь-якому механізмі перевірки. Вони обидва мають намір взяти на себе відповідальність за відображення сповіщень з усіма розробленими варіантами розміщення, обгортки, стилі, коли все, що я шукаю - це тип (и) помилок (мені не обов'язково навіть потрібен текст повідомлення) та елемент, який він стосується до. Я знайшов хуки для всієї форми, а не для окремих сповіщень.

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

У когось є рішення чи краща ідея?

Відповіді:


21

Погляньте на параметри highlightі showErrors jQuery Validator , вони дозволять вам підключити власні підказки про помилки, які викликають появу Bootstrap.


Це чудово, дякую. виділення та непросвіт - те, що я шукав.
Synchro

80

Це практичний приклад:

$('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); 
    }
});

введіть тут опис зображення

Він насправді не використовує завантажувальні поповери, але виглядає дуже приємно і легко досягти.

ОНОВЛЕННЯ

Отже, для перевірки 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 .


3
Прихильний, бо це в напрямку того, що я шукав. :-) Дивіться мою відповідь на варіант.
намін

Що робити, якщо це багатоступенева форма
Тахіони

4
Просто коротко зауважте, що в останній версії Bootstrap більше немає ключа .data ("popover"). Можливо, щоб уникнути зіткнення вони змінили ключ на "bs.popover". Мені знадобився час, щоб зрозуміти, чому я отримую невизначену помилку. Тож тепер вам потрібно буде використовувати _popover.data ("bs.popover"). Options.content = value.message; у коді вище.
davidethell

Як я можу відобразити спливаюче вікно з іншим типом помилки, крім обов’язкових полів. Я маю на увазі сказати, як я можу налаштувати його на відображення помилок лише за певними правилами.
Арджун

Насправді є невелика проблема, яку ви також можете легко перевірити у jsFiddle. Якщо поле не є обов'язковим, і якесь правило порушено, покажчик відображається, АЛЕ якщо я спорожню поле та зосереджуюся на іншому полі, покажчик все ще є. Перший цикл у списку успіху ніколи не викликається, тому поповер ніколи не перебуває в стані "приховування" після того, як він потрапляє в стан "шоу". Чи можемо ми з цим щось зробити?
G4bri3l

9

Кріс Фулстоу мав це правильно, але це все одно зайняло у мене деякий час, тому ось повний код:

Це показує вікно помилки та приховує мітки помилок за замовчуванням:

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

Це налаштовує поповер. Єдине, що вам потрібно з цього, - це тригер: 'manual'

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

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

Це спрацьовує, але поповер мерехтить після скасування вибору. Будь-яка ідея, як це виправити?


6

Ось продовження чудової пропозиції від Варуна Сінгха, яка запобігає проблемі "мерехтіння" перевірки, яка постійно намагається "показати", хоча спливаюче вікно вже присутнє. Я просто додав масив станів помилок, щоб зафіксувати, які елементи відображають помилки, а які ні. Працює як оберіг!

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

Це була єдина відповідь на цій сторінці, яка працювала для мене. Соромно, що його не проголосували більше.
alastairs

1
Чи не означає це, що вам потрібно чітко визначити popoverкожне поле, яке ви хочете перевірити? Якщо так, то це горіхи .
g33kz0r

Для більшості випадків використання, я сподіваюся, це цілком прийнятно. Якщо у вас є більш оптимальне рішення, сміливо додайте його :)
Джеффрі Гілберт,

5

Це розширення jQuery для плагіна перевірки jQuery (протестовано з версією 1.9.0) зробить трюк.

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

Це також додає в деяких повідомленнях про помилки Rails-esk.


Це чудово. Дуже корисно. Тепер, щоб зрозуміти, як отримати відповідне повідомлення для прапорця TOS ...
tig

3

Я вважаю за краще змінити CSS бутстрапа. Щойно додані класи jQuery перевіряють у потрібному місці. помилка перевірки поля та помилка перевірки вводу

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

Для мене такий підхід виглядає найкраще :). Це також те, про що я думав
Freshblood

3

Ось як я це зробив із Bootstrap 2.x та jQuery Validate 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');
    }});

3

Будь ласка, подивіться на таке:
- https://gist.github.com/3030983
Я думаю, що це найпростіше з усіх.

РЕДАГУВАТИ

Код за посиланням:

$('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, але з підказками. На мій погляд, це більш елегантно, ніж поповер.
Адріан П.

3

Велике спасибі за голови! Ось моя версія для Bootstrap, але з підказками. На мій погляд, це більш елегантно, ніж поповер. Я знаю, що питання стосувалось поповерів, тому, будь ласка, не голосуйте з цієї причини. Можливо, комусь так сподобається. Я люблю, коли щось шукаю, і знайшов нові ідеї на 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');

            });

        }

    }); 

1
Я намагався використати ваш підхід, але я починав отримувати помилки. Проблема полягає в тому, що якщо ви використовуєте інтерфейс Jquery, ви отримаєте конфлікт, оскільки обидва використовують підказку. Я знаю, що для цього є рішення, але просто хочу, щоб інші користувачі про це знали.
Річард Перес

+1 Для користувацького інтерфейсу jQuery! Вам доведеться налаштувати власне завантаження (jQueryUI або Bootstrap), щоб НЕ включати функції підказки JS. У будь-якому випадку для будь-якої підказки це буде конфліктом, якщо ви цього не зробили.
Адріан П.

привіт, я намагався використати ваш код із регулярним виразом, і трапилася помилка на stackoverflow.com/questions/16087351/… . Як ви думаєте, чи можете ви допомогти? :)
psharma

@psharma Нічого спільного з початковою стрічкою чи підказкою. Ваша помилка - це ваша декларація правила, оскільки ви отримали відповідь на своє запитання. у повідомленні про помилку сказано: терміни невизначені!
Адріан П.

Чомусь це єдине рішення, яке спрацювало для мене. Дякую!
suchanoob

2

Ось як я це зробив. Але це передбачає внесення 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.validate.js
1. застосувати це виправлення - https://github.com/bsrykt/jquery-validation/commit/6c3f53ee00d8862bd4ee89bb627de5a53a7ed20a
2. Після рядка 647 (у функції showLabel створити частину мітки ) після рядка .addClass(this.settings.errorClass)додати рядок: .addClass("help-inline")
Хтось може знайти спосіб застосувати друге виправлення у функції перевірки, але я не знайшов способу, оскільки showLabel викликається після виділення.


2

Це те, що я вклав у свою валідацію, щоб відповідати вимогам Twitter Bootstrap. Повідомлення про перевірку помилки поміщається в a, <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');
}

2

Ось оновлення чудової відповіді Кенні Мейєра вище . Було кілька питань, які заважали йому працювати для мене, і я розглянув їх у цьому фрагменті:

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

Дякую за ініціативу. Я бачу, що код дуже змінився :-)
Кенні Мейер,

1

Не впевнений, чи це має відношення до обговорення, оскільки оригінальний плакат просив гачки, щоб показати / приховати поповери завантаження.

Я шукав просту перевірку, і поповери не мали значення. Родинний пост і першим в результатах пошуку Google вже відзначений дублікат цього питання. Тож мало сенс згадати цей чудовий jqValidation JS @ ReactiveRaven, влучно названий jqBootstrapValidation, який добре поєднується з Twitter Bootstrap. Налаштування займає лише кілька хвилин. Завантажте тут .

Сподіваюся, це додає вартості.


1

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

Ось моя думка, яка виправляє проблему мерехтіння, згадану іншими, але, на відміну від відповіді @Jeffrey Gilbert, не використовує list ( errorStates), а використовує карту помилок . Хеш-карти FTW. Здається, я пам’ятаю, десь читав, що кожну проблему в 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");
      }
    });
  }
});

Дякуємо всім, хто розміщував ідеї щодо цього.



0

Якщо ви використовуєте наведений вище код Кені Кейєра для спливаючих вікон, будьте обережні, що правила, які перевіряють вміст поля, але не є обов’язковими, наприклад, діюча URL-адреса, призведуть до того, що спливаюче вікно не зникне при очищенні поля. Дивіться нижче onkeyup для рішення. Якщо хтось має краще рішення, будь ласка, напишіть.

onkeyup: function(element, event) {
            if($(element).valid())  {
                return $(element).popover("hide");
            }
        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.