如何使用Twitter Bootstrap弹出窗口进行jQuery验证通知?


84

我可以很容易地使用引导程序使弹出窗口显示出来,也可以使用标准的jQuery验证插件jQuery验证引擎进行验证,但是我不知道如何将它们引入另一个。

我认为我需要的是验证器要显示通知时调用的钩子,为它提供一个闭包,将消息和目标元素传递给弹出框。这似乎是一种依赖注入。

从理论上讲一切都很好,但我只是无法弄清楚该钩子在哪里,或者即使在任一验证引擎中都存在。他们俩似乎都打算承担显示通知的责任,这些通知带有错误,错误类型(我甚至不一定需要消息文本)及其相关元素,以便显示通知,其中包含各种精美的布局,包装,样式选项至。我找到了整个表单的钩子,而不是单个通知的钩子。

我更喜欢使用类定义规则的验证系统,因为它们可以很好地与动态创建的表单一起使用。

任何人都有解决方案或更好的主意吗?

Answers:



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

在此处输入图片说明

它实际上并没有使用引导程序弹出窗口,但是看起来非常不错并且很容易实现。

更新

因此,要进行弹出验证,可以使用以下代码:

$("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
已提出支持,因为这符合我的要求。:-)看到我的答案的变种。
namin 2012年

如果它是多阶段形式,该怎么办
Tachyons 2013年

4
请注意,在最新版本的Bootstrap中,不再有.data(“ popover”)键。为了避免冲突,他们将密钥更改为“ bs.popover”。花了我一段时间才能弄清楚为什么我得到一个未定义的错误。因此,现在您需要使用_popover.data(“ bs.popover”)。options.content = value.message; 在上面的代码中。
davidethell 2013年

除了必填字段外,如何显示其他错误类型的弹出窗口。我的意思是说我该如何自定义它以仅在特定规则上显示错误。
arjun

实际上,您还可以轻松地在jsFiddle中检出一个小问题。如果不需要该字段并且某些规则被打破,则如果我清空该字段并专注于另一个字段,则弹出窗口会显示出来,但弹出窗口仍然存在。不会调用successList上的第一个循环,因此弹出窗口进入“显示”状态后再也不会处于“隐藏”状态。我们有什么可以做的吗?
G4bri3l 2014年

9

克里斯·富尔斯托(Chris Fulstow)没错,但仍然花了我一段时间,所以这里是完整的代码:

这将显示错误弹出框,并隐藏默认错误标签:

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

这将设置弹出窗口。您唯一需要的是触发器:“手动”

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

传递给popover的title和content属性不起作用,因此我在#password输入中以data-content ='最少5个字符'和data-original-title ='Invalid Password'的形式内联指定了它们。您还需要表单中的rel ='popover'。

这可行,但是取消选中后,弹出窗口会闪烁。任何想法如何解决?


6

这是Varun Singh提出的出色建议的后续措施,该建议可以防止验证的“闪烁”问题不断尝试“显示”,即使已经存在弹出窗口也是如此。我只是添加了一个错误状态数组来捕获哪些元素显示了错误,哪些没有显示。奇迹般有效!

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

对于大多数用例,我希望这是完全可以接受的。如果您有更好的解决方案,请随时添加:)
Jeffrey Gilbert 2014年


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版本,但附带工具提示。我认为它比弹出窗口更优雅。
Adrian P.

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 UI,则会因为两个都使用工具提示而发生冲突。我知道有解决方案,但是只想让其他用户知道。
理查德·佩雷斯

+1对于jQuery UI请注意!您必须将自定义下载(jQueryUI或Bootstrap)配置为不包含Tooltip JS函数。如果您未这样做,那么对于任何工具提示都将是一个冲突。
Adrian P.

嘿,我试图在正则表达式中使用您的代码,并在stackoverflow.com/questions/16087351/…碰巧出现错误。您认为您可以提供帮助吗?:)
psharma

@psharma与引导程序或工具提示无关。您的错误是您的规则声明,因为您对问题有答案。错误消息说:条款未定义!
Adrian P.

由于某种原因,这是唯一对我有用的解决方案。谢谢!
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);
    }
  }
});

然后,您需要更改jquery.validate.js中的2件事
1.应用此修复程序-https : //github.com/bsrykt/jquery-validation/commit/6c3f53ee00d8862bd4ee89bb627de5a53a7ed20a
2.在第647行之后(在showLabel函数中,创建标签部分后)行.addClass(this.settings.errorClass)添加一行:.addClass("help-inline")
有人也许可以找到一种方法,适用于在验证函数的第二个补丁,但我还没有找到一种方法,因为showLabel是亮点后调用。


2

这就是我在验证中输入的内容,以符合Twitter Bootstrap指南。错误验证消息放在<span class=help-inline>,我们要突出显示外部容器为errorsuccess

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

这是Kenny Meyer上面出色答案的更新。有几个问题使它无法为我工作,我已在本摘要中解决了这些问题:

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

不确定这是否与讨论有关,因为原始海报要求使用钩子来显示/隐藏自举程序弹出窗口。

我一直在寻找简单的验证,弹出窗口没关系。一个相关的职位,并在谷歌搜索结果的第一已经被标记重复这一问题。因此,有必要提及这个出色的@ReactiveRaven的jqValidation JS(恰当地称为jqBootstrapValidation),它与Twitter Bootstrap结合得很好。安装仅需几分钟。在这里下载。

希望这能增加价值。


1

tl; dr避免需要枚举枚举,方法是使用哈希映射存储元素的id,并动态创建弹出窗口(混搭Jeffrey Gilbert和Kenny Meyer的方法)。

这是我的观点,它解决了其他人提到的闪烁问题,但是与@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

如果将上述Kenny Meyer代码用于弹出窗口,请注意检查字段内容但不需要的规则(例如有效的URL)将导致弹出窗口在清除字段时不会消失。有关解决方案,请参见下面的onkeyup。如果有人有更好的解决方案,请发布。

onkeyup: function(element, event) {
            if($(element).valid())  {
                return $(element).popover("hide");
            }
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.