web-dev-qa-db-ja.com

MVC Twitter Bootstrap目立たないエラー処理

私はしばらくの間、MVCJqueryの目立たないエラー処理をTwitter bootstrapで動作させようとしてきました。それは、jquery.validateを編集するか、ハックを行うかという点に到達しました。 document.readyをスラッシュします。

目立たないエラー処理をBootstrapおよびMVCで機能させるには、 'error'クラスが 'control-group'クラスに追加されるようにする必要があります。 'error'クラスが入力に追加されます。

コミュニティの誰かがすでに解決策を見つけているかどうか疑問に思いました。

例えば

典型的なbootstrapマークアップは次のようになります...

<div class="control-group">
    <label for="Username">Username</label>
    <div class="controls">
        <input data-val="true" data-val-required="Username is required" id="Username" name="Username" type="text" value="" />
        <span class="field-validation-valid" data-valmsg-for="Username" data-valmsg-replace="true"></span>
    </div>
</div>

Jquery.validateが目立たないように起動したときにブラーするとどうなるか...次のように変更されます

<div class="control-group error">
    <label for="Username">Username</label>
    <div class="controls">
        <input data-val="true" data-val-required="Username is required" id="Username" name="Username" type="text" value="" />
        <span class="field-validation-valid help-inline" data-valmsg-for="Username" data-valmsg-replace="true"></span>
    </div>
</div>

これをポストバック/送信で機能させるには、次のようにします...

//Twitter bootstrap on post
$(function () {
    $('span.field-validation-valid, span.field-validation-error').each(function () {
        $(this).addClass('help-inline');
    });

    $('form').submit(function () {
        if ($(this).valid()) {
            $(this).find('div.control-group').each(function () {
                if ($(this).find('span.field-validation-error').length == 0) {
                    $(this).removeClass('error');
                }
            });
        }
        else {
            $(this).find('div.control-group').each(function () {
                if ($(this).find('span.field-validation-error').length > 0) {
                    $(this).addClass('error');
                }
            });
        }
    });


    $('form').each(function () {
        $(this).find('div.control-group').each(function () {
            if ($(this).find('span.field-validation-error').length > 0) {
                $(this).addClass('error');
            }
        });
    });

});

ただし、ぼかしをかけると、期待どおりに機能しません。 bootstrap CSS、またはJquery.validateファイルは、ある時点で更新をロールアウトする可能性があるため、編集したくありません。

デリゲートを作成するか、jquery関数にバインドして、そこから作業しますか?これは私がよく知らない深いJSコードですが、時間の経過とともにそれを通り抜けることができます。

私がこの問題をどこから始めればよいか、またはどこで実装/議論されているかを知っている人はいますか?

24
Adam
var page = function () {
    //Update that validator
    $.validator.setDefaults({
        highlight: function (element) {
            $(element).closest(".control-group").addClass("error");
        },
        unhighlight: function (element) {
            $(element).closest(".control-group").removeClass("error");
        }
    });
} ();

最後に、これは私のためにそれを修正しました。これが他の人にも役立つことを願っています...

私の最後のJSはそのように終わりました。

$(function () {
    $('span.field-validation-valid, span.field-validation-error').each(function () {
        $(this).addClass('help-inline');
    });

    $('form').submit(function () {
        if ($(this).valid()) {
            $(this).find('div.control-group').each(function () {
                if ($(this).find('span.field-validation-error').length == 0) {
                    $(this).removeClass('error');
                }
            });
        }
        else {
            $(this).find('div.control-group').each(function () {
                if ($(this).find('span.field-validation-error').length > 0) {
                    $(this).addClass('error');
                }
            });
        }
    });


    $('form').each(function () {
        $(this).find('div.control-group').each(function () {
            if ($(this).find('span.field-validation-error').length > 0) {
                $(this).addClass('error');
            }
        });
    });

});


var page = function () {
    //Update that validator
    $.validator.setDefaults({
        highlight: function (element) {
            $(element).closest(".control-group").addClass("error");
        },
        unhighlight: function (element) {
            $(element).closest(".control-group").removeClass("error");
        }
    });
} ();
28
Adam

これが素晴らしい解決策です...

これをjQuery(document).ready()の外の__Layout.cshtml_ファイルに追加します。

_<script type="text/javascript">

jQuery.validator.setDefaults({
    highlight: function (element, errorClass, validClass) {
        if (element.type === 'radio') {
            this.findByName(element.name).addClass(errorClass).removeClass(validClass);
        } else {
            $(element).addClass(errorClass).removeClass(validClass);
            $(element).closest('.control-group').removeClass('success').addClass('error');
        }
    },
    unhighlight: function (element, errorClass, validClass) {
        if (element.type === 'radio') {
            this.findByName(element.name).removeClass(errorClass).addClass(validClass);
        } else {
            $(element).removeClass(errorClass).addClass(validClass);
            $(element).closest('.control-group').removeClass('error').addClass('success');
        }
    }
});

</script>
_

これを$(document).ready()内に追加します:

_$("span.field-validation-valid, span.field-validation-error").addClass('help-inline');
$("div.control-group").has("span.field-validation-error").addClass('error');
$("div.validation-summary-errors").has("li:visible").addClass("alert alert-block alert-error");
_

あなたは行ってもいいです。


から取られたコード部分:

Twitter Bootstrap ASP.NET MVCを使用した検証スタイル

統合Bootstrap MVCの目立たないエラー検証によるエラースタイリング

@ davebの答え

10

@ leniel-macaferiによって提供される answer に加えて、$(document).ready()関数として以下を使用します。

$(function () {
    $("span.field-validation-valid, span.field-validation-error").addClass('help-inline');
    $("div.control-group").has("span.field-validation-error").addClass('error');
    $("div.validation-summary-errors").has("li:visible").addClass("alert alert-block alert-error");
});

これはまた、サーバー側の検証がフォーム投稿で失敗した場合にコントロールグループに「エラー」クラスを設定し、検証の概要をbootstrapエラーアラートとして適切にフォーマットします。

6
daveb

私はこれが古いことを知っていますが、Bootstrap 3.の更新に対する私の答えを共有したいと思いました。LenielMacaferiによって提供されたソリューションの上に構築する前に、かなり長い間頭を悩ませました。

Bootstrap 3を反映するようにクレースを変更することに加えて、フィールドの状態を表すグリフィコンをユーザーに提示するのはいい感じだと思いました。

(function ($) {
var defaultOptions = {
    errorClass: 'has-error has-feedback',
    validClass: 'has-success has-feedback',
    highlight: function (element, errorClass, validClass) {
        var _formGroup = $(element).closest(".form-group");
        _formGroup
            .addClass('has-error')
            .removeClass('has-success');

        if (!_formGroup.hasClass("has-feedback")) {
            _formGroup.addClass("has-feedback");
        }

        var _feedbackIcon = $(element).closest(".form-group").find(".glyphicon");
        if (_feedbackIcon.length) {
            $(_feedbackIcon)
                .removeClass("glyphicon-ok")
                .removeClass("glyphicon-remove")
                .addClass("glyphicon-remove");
        }
        else {
            $("<span class='glyphicon glyphicon-remove form-control-feedback' aria-hidden='true'></span>")
                .insertAfter(element);
        }
    },
    unhighlight: function (element, errorClass, validClass) {
        var _formGroup = $(element).closest(".form-group");
        _formGroup
            .removeClass('has-error')
            .addClass('has-success');

        if (!_formGroup.hasClass("has-feedback")) {
            _formGroup.addClass("has-feedback");
        }

        var _feedbackIcon = $(element).closest(".form-group").find(".glyphicon");
        if (_feedbackIcon.length) {
            $(_feedbackIcon)
                .removeClass("glyphicon-ok")
                .removeClass("glyphicon-remove")
                .addClass("glyphicon-ok");
        }
        else {
            $("<span class='glyphicon glyphicon-ok form-control-feedback' aria-hidden='true'></span>")
                .insertAfter(element);
        }
    }
};

$.validator.setDefaults(defaultOptions);

$.validator.unobtrusive.options = {
    errorClass: defaultOptions.errorClass,
    validClass: defaultOptions.validClass,
};

})(jQuery);
4
aplon

私が作成したこのプラグインを使用してみてください https://github.com/sandrocaseiro/jquery.validate.unobtrusive.bootstrap

私が他の回答と異なって行ったことは、validate.unobtrusiveのerrorPlacementメソッドとsuccessメソッドを自分の実装でオーバーライドすることでしたが、元の実装を削除せずに、何も壊れません。

私の実装は次のようになります。
erroPlacement:

function onError(formElement, error, inputElement) {
    var container = $(formElement).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
        replaceAttrValue = container.attr("data-valmsg-replace"),
        replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;

    //calling original validate.unobtrusive method
    errorPlacementBase(error, inputElement);

    if (replace) {
        var group = inputElement.parent();
        if (group.hasClass('form-group')) {
            group.addClass('has-error').removeClass('has-success');
        }
        group = group.parent();
        if (group.hasClass('form-group')) {
            group.addClass('has-error').removeClass('has-success');
        }
    }
}

成功:

function onSuccess(error) {
    var container = error.data("unobtrusiveContainer");

    //calling original validate.unobtrusive method
    successBase(error);

    if (container) {
        var group = container.parent();
        if (group.hasClass('form-group')) {
            group.addClass('has-success').removeClass('has-error');
        }
        group = group.parent();
        if (group.hasClass('form-group')) {
            group.addClass('has-success').removeClass('has-error');
        }
    }
}
2
SandroCaseiro

箱から出して、エラー検証を上げるためにぼかしを入れたかったのです。 JqueryUnobtrusiveの場合はそうではないことがわかりました。選択入力があるがテキストタイプ入力ではない場合は機能するように見えました。私のためにこれを回避するために、おそらくそれは不器用ですが、私は以下を使用しました。

$(function () {
    $("input[type='text']").blur(function () {
        $('form').validate().element(this);
    });
});

特定のcssクラスを持つ特定の入力で有効になるように変更できます。

$(function () {
    $(".EnableOnblurUnobtrusiveValidation").blur(function () {
        $('form').validate().element(this);
    });
});

EnableOnblurUnobtrusiveValidation ...は少し長い名前ですが、要点はわかります。

0
Adam

TwitterBootstrapMvc を使用します。

目立たない検証属性を自動的に処理し、ラベル、入力、検証を含む完全なコントロールグループを取得するために作成する必要があるのは次のとおりです。

@Html.Bootstrap().ControlGroup().TextBoxFor(x => x.Field)

幸運を!

0
Dmitry Efimenko