2

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

2 つ目の注意点として、javascript が無効になっている場合に機能を変更しないようにするには、どうすればこれを改善できますか?

4

1 に答える 1

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);
于 2012-06-23T16:29:25.657 に答える