MVC Twitter Bootstrap unobtrusive error handling

混江龙づ霸主 提交于 2019-11-29 19:39:05
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");
        }
    });
} ();

Finally, this fixed it for me. I hope this helps other people too...

My final JS ended like so.

$(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");
        }
    });
} ();
Leniel Maccaferri

Here's a nice solution...

Add this to your _Layout.cshtml file outside jQuery(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>

Add this inside $(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");

You're good to go.


Code pieces taken from:

Twitter Bootstrap validation styles with ASP.NET MVC

Integrating Bootstrap Error styling with MVC’s Unobtrusive Error Validation

@daveb's answer

daveb

In addition to the answer provided by @leniel-macaferi I use the following as my $(document).ready() function:

$(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");
});

This also sets the "error" class on the control group if server side validation has failed on a form post and formats any validation summary nicely as a bootstrap error alert.

I know this is an oldy, but I thought I'd share my answer to update for Bootstrap 3. I scratched my head for quite sometime, before building on top of the solution given by Leniel Macaferi.

On top of changing the clases to reflect Bootstrap 3, I thought it would be a nice touch to present the user with a glyphicon to represent the state of the field.

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

Try use this plugin I've made https://github.com/sandrocaseiro/jquery.validate.unobtrusive.bootstrap

What I did differently from the others answers was to override the errorPlacement and success methods from validate.unobtrusive with my own implementations, but without removing the original implementation so nothing will break.

My implementation look like this:
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');
        }
    }
}

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

Out of the box I wanted on blur to raise my error validation. I found this wasn't the case with Jquery Unobtrusive. It seemed to work if you had a select input but not on a text type input. To get around this for me, perhaps its clumsy but I used the following.

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

You can change it is just enabled on certain inputs that have a specific css class.

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

EnableOnblurUnobtrusiveValidation... is a bit of a long name but you get the jist.

Dmitry

Use TwitterBootstrapMvc.

It takes care of unobtrusive validation attributes automatically and all you have to write to get a full control group with label, input and validation is:

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

Good luck!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!