MVC Twitter Bootstrap 非显眼错误处理

MVC Twitter Bootstrap unobtrusive error handling

提问人:Adam 提问时间:4/19/2012 最后编辑:Leniel MaccaferriAdam 更新时间:2/14/2015 访问量:15247

问:

一段时间以来,我一直在尝试让 MVC Jquery 不显眼的错误处理与 twitter bootstrap 一起使用。到了我要么编辑jquery.validate,要么对document.ready进行一些砍杀和砍杀。

为了使不显眼的错误处理与 Bootstrap 和 MVC 一起使用,我需要使它附加到“control-group”类的“error”类。除此之外,“error”类被附加到输入中。

我想知道社区中是否有人已经找到了解决方案。

例如

典型的引导标记是这样的......

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

});

但是,在模糊时,它不会像您预期的那样工作。我不想编辑引导 CSS 或 Jquery.validate 文件,因为它们可能会在某个时候推出更新。

我会创建一个委托,还是一个绑定到jquery函数,然后从那里开始工作。这是我不熟悉的深度 JS 代码,但随着时间的推移,我可以解决它。

有没有人知道我从哪里开始解决这个问题,或者知道它是在哪里实施/讨论的?

css asp.net-mvc 验证 twitter-bootstrap unobtrusive-javascript

评论

0赞 rlemon 4/19/2012
问题在哪里?我看到更多没有代码或特定问题的请求!如果你能提供一个示例,说明“MVC Jquery unobtrusive error handling”在 twitter bootstrap 中失败,这个问题可能是可以回答的。
0赞 Adam 4/19/2012
只是更新我的帖子。这是我第一次来这里,所以我为菜鸟主义道歉:s

答:

28赞 Adam 4/20/2012 #1
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");
        }
    });
} ();

评论

0赞 Miika L. 6/5/2012
form.submit 的代码运行良好,但如果输入中的某些内容得到纠正,它似乎不会删除错误类(但其他内容仍然阻止操作通过)。你知道这是为什么吗?
0赞 Miika L. 6/5/2012
如果将查找“有效”字段的循环移动到 if 语句之外,则它将正确执行以删除错误类。
0赞 Adam 4/21/2012 #2

开箱即用,我想在模糊上提高我的错误验证。我发现Jquery Unobtrusive并非如此。如果您有选择输入,但对文本类型输入没有,它似乎有效。为了解决这个问题,也许它很笨拙,但我使用了以下内容。

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

您可以更改它只是在具有特定 css 类的某些输入上启用。

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

EnableOnblurUnobtrusiveValidation...名字有点长,但你明白了。

10赞 Leniel Maccaferri 2/2/2013 #3

这是一个不错的解决方案......

将此添加到您的文件外部:_Layout.cshtmljQuery(document).ready()

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

你已经准备好了。


代码片段摘自:

使用 ASP.NET MVC 的 Twitter Bootstrap 验证样式

将 Bootstrap Error 样式与 MVC 的 Unobtrusive Error Validation 集成

@daveb的答案

-1赞 Dmitry Efimenko 7/8/2013 #4

使用 TwitterBootstrapMvc

它会自动处理不显眼的验证属性,要获得带有标签、输入和验证的完整控制组,您只需编写以下内容:

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

祝你好运!

评论

0赞 ta.speot.is 7/28/2013
客户端验证的样式与服务器端的模型无效时的样式不同。我认为你仍然需要 stackoverflow.com/a/14650921/242520
0赞 Dmitry Efimenko 7/28/2013
样式完全取决于 CSS。
0赞 ta.speot.is 7/28/2013
是的,MVC4 的不显眼验证添加了类似 的类,而 Bootstrap 具有类似 .TwitterBootstrapMvc 在生成标记时(当模型无效时)添加,但这只是验证发生时间的一半。braindonor.net/blog/......field-validation-errorerrorerror
0赞 Dmitry Efimenko 7/28/2013
我明白你的意思了。类错误仅在服务器验证中添加。嗯,是的,TwitterBootstrapMVC 没有与 javascript 一起出现。也许它应该......
6赞 daveb 8/9/2013 #5

除了 @leniel-macaferi 提供的答案外,我还使用以下内容作为我的 $(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");
});

如果服务器端验证在表单发布上失败,这还会在控制组上设置“错误”类,并将任何验证摘要很好地格式化为引导错误警报。

评论

1赞 Leniel Maccaferri 10/2/2013
男人。。。我正在寻找服务器验证错误的情况。我看到该类没有添加到<div>中。你救了我!:)StackOverflow 真是太棒了!!一个答案建立在另一个答案之上......世界就是这样演变的。error.control-group
2赞 SandroCaseiro 2/10/2014 #6

尝试使用我制作的这个插件 https://github.com/sandrocaseiro/jquery.validate.unobtrusive.bootstrap

我与其他答案的不同之处在于用我自己的实现覆盖validate.untrusive中的and方法,但不删除原始实现,因此不会破坏任何内容。errorPlacementsuccess

我的实现如下所示: 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');
        }
    }
}
4赞 aplon 2/14/2015 #7

我知道这是一个老生常谈的问题,但我想我会分享我的答案来更新 Bootstrap 3。我挠了好一阵子,然后才在Leniel Macaferi给出的解决方案之上进行构建。

除了更改 clases 以反映 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);

评论

0赞 Willy 11/8/2017
感谢您的代码,但是如果您使用 AJAX 和部分视图提交,它将不起作用,您能帮忙吗?