Any Way to Implement Twitter Bootstrap using MVC 4 validation? Instead of using jquery?

10,938

Solution 1

Here's an HtmlHelper extension method that will use the Twitter Bootstrap error alert (listing the model errors).

Useage:

@Html.ValidationSummaryBootstrap();

Result example for multiple model errors:

multiple errors example

A single model error would result in something like this: single error example

Here's the code: (To get the fields highlighted too - see the bottom of this answer).

using System.Linq;

namespace System.Web.Mvc
{
    public static class HtmlExtensionMethods
    {
        /// <summary>
        /// Returns an error alert that lists each model error, much like the standard ValidationSummary only with
        /// altered markup for the Twitter bootstrap styles.
        /// </summary>
        public static MvcHtmlString ValidationSummaryBootstrap(this HtmlHelper helper, bool closeable)
        {
            # region Equivalent view markup
            // var errors = ViewData.ModelState.SelectMany(x => x.Value.Errors.Select(y => y.ErrorMessage));
            //
            // if (errors.Count() > 0)
            // {
            //     <div class="alert alert-error alert-block">
            //         <button type="button" class="close" data-dismiss="alert">&times;</button>
            //         <strong>Validation error</strong> - please fix the errors listed below and try again.
            //         <ul>
            //             @foreach (var error in errors)
            //             {
            //                 <li class="text-error">@error</li>
            //             }
            //         </ul>
            //     </div>
            // }
            # endregion

            var errors = helper.ViewContext.ViewData.ModelState.SelectMany(state => state.Value.Errors.Select(error => error.ErrorMessage));

            int errorCount = errors.Count();

            if (errorCount == 0)
            {
                return new MvcHtmlString(string.Empty);
            }

            var div = new TagBuilder("div");
            div.AddCssClass("alert");
            div.AddCssClass("alert-error");

            string message;

            if (errorCount == 1)
            {
                message = errors.First();
            }
            else
            {
                message = "Please fix the errors listed below and try again.";
                div.AddCssClass("alert-block");
            }

            if (closeable)
            {
                var button = new TagBuilder("button");
                button.AddCssClass("close");
                button.MergeAttribute("type", "button");
                button.MergeAttribute("data-dismiss", "alert");
                button.SetInnerText("x");
                div.InnerHtml += button.ToString();
            }

            div.InnerHtml += "<strong>Validation error</strong> - " + message;

            if (errorCount > 1)
            {
                var ul = new TagBuilder("ul");

                foreach (var error in errors)
                {
                    var li = new TagBuilder("li");
                    li.AddCssClass("text-error");
                    li.SetInnerText(error);
                    ul.InnerHtml += li.ToString();
                }

                div.InnerHtml += ul.ToString();
            }

            return new MvcHtmlString(div.ToString());
        }

        /// <summary>
        /// Overload allowing no arguments.
        /// </summary>
        public static MvcHtmlString ValidationSummaryBootstrap(this HtmlHelper helper)
        {
            return ValidationSummaryBootstrap(helper, true);
        }
    }
}

For the individual fields I've been a bit lazy and just coded it into the views (to be refactored).

<div class="control-group @if (!ViewData.ModelState.IsValidField("UserName")) { @Html.Raw("error"); }">
    <label class="control-label" for="UserName">User name</label>
    <div class="controls">
        <div class="input-prepend input-append">
            <span class="add-on"><i class="icon-user"></i></span>
            @Html.TextBoxFor(x => x.UserName, new { @class = "input-medium", @required = true })
            <input class="btn" type="button" value="Check" />
        </div>
    </div>
</div>

Solution 2

Use TwitterBootstrapMvc.

For the validation summary you can use the following syntax:

@Html.Bootstrap().ValidationSummary()

It will render an alert with all errors listed just like in the answer by PeteGo. However, in contrast to the answer by PeteGo, for individual fields it's enough to write something like this:

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

This helper takes care of all unobtrusive validation attributes as well.


Disclaimer: I'm the author of BMVC. Using it is Bootstrap 2 is free. For Bootstrap 3 it requires a license.

Solution 3

Give a look at these Visual Studio templates. They implement validation using the MVC4 way. It's more of what you need, but you can get the validation script they use and then utilize it in your own project.

BootstrapScaffoldMVCTemplates

BootstrapScaffoldMVCTemplates are meant to be used along with MVC 4 TwitterBootstrap Starter Layout Page (Razor) .

Share:
10,938
xJedx
Author by

xJedx

Updated on June 26, 2022

Comments

  • xJedx
    xJedx over 1 year

    As mentioned in the title, any advice would be appreciated. Also, anyway to know how to implement jquery to post data from dropdown list, checked box over to MVC 4 server side and responding back? Like, wow to implement System.Web.Mvc.Html and System.Web.Mvc.Ajax libraries with Twitter Bootstrap component?

    http://twitter.github.com/bootstrap/ There is no way to show how to implement those information mentioned above.