钩子jQuery验证消息的变化

时间:2012-06-23 00:53:19

标签: javascript jquery html css asp.net-mvc-3

我想在工具提示中显示我的jQuery验证消息。为了实现这一点,我首先在样式表中添加了以下CSS规则:

fieldset .field-validation-error {
    display: none;
}

fieldset .field-validation-error.tooltip-icon {
    background-image: url('/content/images/icons.png');
    background-position: -32px -192px;
    width: 16px;
    height: 16px;
    display: inline-block;
}

和一小段JS代码:

; (function ($) {
    $(function() {
        var fields = $("fieldset .field-validation-valid, fieldset .field-validation-error");
        fields.each(function() {
            var self = $(this);
            self.addClass("tooltip-icon");
            self.attr("rel", "tooltip");
            self.attr("title", self.text());
            self.text("");
            self.tooltip();
        });
    });
})(jQuery);

问题是我现在需要在验证消息发生变化时捕获任何事件,我一直在查看jquery.validate.unobtrusive.js的来源,而我需要挂钩的方法是function onError(error, inputElement)方法。

只要我更新了title属性,我的工具提示插件就可以运行,当重新验证字段时会出现问题,并且重新生成验证消息,我需要将其挂钩并防止将消息放在那里并将其放在title属性中。

我想找到一种方法来执行此操作而无需修改实际的jquery.validate.unobtrusive.js文件。

在第二个注释中,我如何改进这一点,以便在javascript被禁用的情况下保持功能不变?

1 个答案:

答案 0 :(得分:2)

好的,我选择了这个,以防万一有人再碰到这个:

; (function ($) {
    $(function() {
        function convertValidationMessagesToTooltips(form) {
            var fields = $("fieldset .field-validation-valid, fieldset .field-validation-error", form);
            fields.each(function() {
                var self = $(this);
                self.addClass("tooltip-icon");
                self.attr("rel", "tooltip");
                self.attr("title", self.text());
                var span = self.find("span");
                if (span.length) {
                    span.text("");
                } else {
                    self.text("");
                }
                self.tooltip();
            });
        }

        $("form").each(function() {
            var form = $(this);
            var settings = form.data("validator").settings;
            var old_error_placement = settings.errorPlacement;
            var new_error_placement = function() {
                old_error_placement.apply(settings, arguments);
                convertValidationMessagesToTooltips(form);
            };
            settings.errorPlacement = new_error_placement;
            convertValidationMessagesToTooltips(form); // initialize in case of model-drawn validation messages at page render time.
        });
    });
})(jQuery);

和样式:

fieldset .field-validation-error { /* noscript */
    display: block;
    margin-bottom: 20px;
}

fieldset .field-validation-error.tooltip-icon { /* javascript enabled */
    display: inline-block;
    margin-bottom: 0px;

    background-image: url('/content/images/icons.png');
    background-position: -32px -192px;
    width: 16px;
    height: 16px;
    vertical-align: middle;
}

我只会包含我所拥有的工具提示脚本,因为它是一种定制的(尽管我是基于其他人的)。

; (function ($, window) {
    $.fn.tooltip = function (){
        var classes = {
            tooltip: "tooltip",
            top: "tooltip-top",
            left: "tooltip-left",
            right: "tooltip-right"
        };

        function init(self, tooltip) {
            if ($(window).width() < tooltip.outerWidth() * 1.5) {
                tooltip.css("max-width", $(window).width() / 2);
            } else {
                tooltip.css("max-width", 340);
            }

            var pos = {
                x: self.offset().left + (self.outerWidth() / 2) - (tooltip.outerWidth() / 2),
                y: self.offset().top - tooltip.outerHeight() - 20
            };

            if (pos.x < 0) {
                pos.x = self.offset().left + self.outerWidth() / 2 - 20;
                tooltip.addClass(classes.left);
            } else {
                tooltip.removeClass(classes.left);
            }

            if (pos.x + tooltip.outerWidth() > $(window).width()) {
                pos.x = self.offset().left - tooltip.outerWidth() + self.outerWidth() / 2 + 20;
                tooltip.addClass(classes.right);
            } else {
                tooltip.removeClass(classes.right);
            }

            if (pos.y < 0) {
                pos.y = self.offset().top + self.outerHeight();
                tooltip.addClass(classes.top);
            } else {
                tooltip.removeClass(classes.top);
            }

            tooltip.css({
                left: pos.x,
                top: pos.y
            }).animate({
                top: "+=10",
                opacity: 1
            }, 50);
        };

        function activate() {
            var self = $(this);
            var message = self.attr("title");
            var tooltip = $("<div class='{0}'></div>".format(classes.tooltip));

            if (!message) {
                return;
            }
            self.removeAttr("title");
            tooltip.css("opacity", 0).html(message).appendTo("body");

            var reload = function() { // respec tooltip's size and position.
                init(self, tooltip);
            };
            reload();
            $(window).resize(reload);

            var remove = function () {
                tooltip.animate({
                    top: "-=10",
                    opacity: 0
                }, 50, function() {
                    $(this).remove();
                });

                self.attr("title", message);
            };

            self.bind("mouseleave", remove);
            tooltip.bind("click", remove);
        };

        return this.each(function () {
            var self = $(this);
            self.bind("mouseenter", activate);
        });
    };

    $.tooltip = function() {
        return $("[rel~=tooltip]").tooltip();
    };
})(jQuery, window);