Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / C#

Bootstrap HTML Helpers

Rate me:
Please Sign up or sign in to vote.
4.99/5 (34 votes)
12 Dec 2012CPOL3 min read 134.6K   105  
With the Bootstrap Helpers project I have made things even easier for .NET developers.
This is an old version of the currently published article.

Introduction

The guys over at Twitter have done a serious favor for developers worldwide with their Bootstrap framework. This is especially useful for us coders with limited skills in UI design. With the Bootstrap Helpers project I have made things even easier for .NET developers.

Usage

Here are some examples of the most useful of HTML helpers using the Razor syntax.

Modal Dialog

C#
<a class="btn" data-toggle="modal" href="#myModal" >Normal Modal</a>

@using (var modal = Html.Bootstrap().Begin(new Modal(new { id = "myModal" })))
{
    using (var header = modal.BeginHeader())
    {
        <button type="button" class="close" 
            data-dismiss="modal"</button>
        <h3>Modal header</h3>
    }
    using (var body = modal.BeginBody())
    {
        <p>One fine body…</p>
    }
    using (var footer = modal.BeginFooter())
    {
        @Html.Bootstrap().Button("Close", BootstrapNamedColor.Default, 
              null, new { data_dismiss = "modal" })
        @Html.Bootstrap().Button("Save Changes", BootstrapNamedColor.Primary, null)
    }
}

Tabs

C#
@using (var tabs = Html.Bootstrap().Begin(new Tabs()))
{
    tabs.Tab("Tab One", "tab1");
    tabs.Tab("Tab Two", "tab2");
    tabs.Tab("Tab Three", "tab3");

    using (tabs.BeginPanel())
    {
        <p>This is tabs panel 1 content</p>
    }
    using (tabs.BeginPanel())
    {
        <p>This is tabs panel 2 content</p>
    }
    using (tabs.BeginPanel())
    {
        <p>This is tabs panel 3 content</p>
    }
}
You could also place the tabs on the left or right. Here is an example:
C#
@using (var tabs = Html.Bootstrap().Begin(new Tabs(TabPosition.Left)))
{
//etc
}

Accordion/Collapse

C#
@using (var accordion = Html.Bootstrap().Begin(new Accordion("accordion1")))
{
    using (var panel = accordion.BeginPanel("Panel 1", "panel1"))
    {
        <p>This is accordion panel 1 content</p>
    }
    using (var panel = accordion.BeginPanel("Panel 2", "panel2"))
    {
        <p>This is accordion panel 2 content</p>
    }
}

Carousel

C#
@using (var carousel = Html.Bootstrap().Begin(new Carousel("carousel1")))
{
    carousel.Item("~/Images/Red.png", "Red");

    using (var item = carousel.ItemWithCaption("~/Images/Green.png", "Green"))
    {
        <h4>This is Green</h4>
        <p>Green is a nice color</p>
    }

    carousel.Item("~/Images/Blue.png", "Blue");
}

Sub Nav

C#
@using (var subNav = Html.Bootstrap().Begin(new SubNavBar()))
{
    subNav.Item("Modal", "#demoModal");
    subNav.Item("Tabs", "#demoTabs");
    subNav.Item("Accordion", "#demoAccordion");
    subNav.Item("Other", "#demoOther");
    subNav.Item("Toolbar", "#demoToolbar");
    subNav.Item("Thumbnails", "#demoThumbs");
    subNav.Item("Carousel", "#demoCarousel");
    subNav.Item("Code Blocks", "#demoCodeBlocks");
    subNav.Item("Forms", Url.Action("DemoForm", "Home"));

    subNav.DropDownItem("DropDown", new List<BootstrapListItem>
    {
        new BootstrapListItem { Text = "Something", Url = "#something" },
        new BootstrapListItem { Text = "Something Else", Url = "#something-else" },
        new BootstrapListItem { Text = "Yet Something More", Url = "#yet-something-more" }
    });
}

Miscellaneous

There are also many smaller helpers which you can find, such as the Buttons. Here is an example of an action button:

C#
@Html.Bootstrap().ActionButton("Home", BootstrapNamedColor.Primary, 
             "Index", "Home")

How it was done

When building any HTML helpers, I consider it always good practice to separate them from the rest of the standard ones. So, instead of calling:

C#
Html.BeginBootstrapAccordion()

or something like that, we want to call:

C#
Html.Bootstrap().Begin(new Accordion())

instead. The way to do this would be to first create a class called Bootstrap with only one constructor whose accessibility is set to internal. Here is an example:

C#
public class Bootstrap<TModel>
{
    private readonly HtmlHelper<TModel> helper;

    internal Bootstrap(HtmlHelper<TModel> helper)
    {
        this.helper = helper;
    }
//etc

You of course need to pass an instance of HtmlHelper as well and in that class is where you will add all the helper methods. Here is a simple example (with overloads):

C#
public MvcHtmlString ActionButton(string text, BootstrapNamedColor color, string actionName, string controllerName)
{
    return ActionButton(text, color, actionName, controllerName, null);
}

public MvcHtmlString ActionButton(string text, BootstrapNamedColor color, 
       string actionName, string controllerName, object routeValues)
{
    return ActionButton(text, color, actionName, controllerName, routeValues, null);
}

public MvcHtmlString ActionButton(string text, BootstrapNamedColor color, 
       string actionName, string controllerName, object routeValues, object htmlAttributes)
{
    var builder = new TagBuilder("a");
    builder.SetInnerText(text);

    builder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

    switch (color)
    {
        case BootstrapNamedColor.Important: builder.AddCssClass("btn btn-danger"); break;
        case BootstrapNamedColor.Default: builder.AddCssClass("btn"); break;
        case BootstrapNamedColor.Info: builder.AddCssClass("btn btn-info"); break;
        case BootstrapNamedColor.Inverse: builder.AddCssClass("btn btn-inverse"); break;
        case BootstrapNamedColor.Primary: builder.AddCssClass("btn btn-primary"); break;
        case BootstrapNamedColor.Success: builder.AddCssClass("btn btn-success"); break;
        case BootstrapNamedColor.Warning: builder.AddCssClass("btn btn-warning"); break;
        default: builder.AddCssClass("btn"); break;
    }

    var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
    builder.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));

    return MvcHtmlString.Create(builder.ToString());
}

Finally, you need to create an instance of the Bootstrap class somewhere. Since it only has an internal constructor, you can only instantiate it from the project it is created in and since you want to be able to use it from any other project, what you do is create a public extension method in that same project like so:

C#
public static class HtmlHelperExtensions
{
    public static Bootstrap<TModel> Bootstrap<TModel>(this HtmlHelper<TModel> htmlHelper)
    {
        return new Bootstrap<TModel>(htmlHelper);
    }
}

And as easy as that you can now add all your helper methods into the Bootstrap “we’ll call it name space; for lack of a better word”. So now I just use it like this:

C#
@Html.Bootstrap().ActionButton("Home", BootstrapNamedColor.Primary, "Index", "Home")

Awesome! Show me more! Okay, okay, here goes: Inspect the following:

C#
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <legend>Registration Form</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName)
            </li>
            <li>
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
            </li>
            <li>
                @Html.LabelFor(m => m.ConfirmPassword)
                @Html.PasswordFor(m => m.ConfirmPassword)
            </li>
        </ol>
        <input type="submit" value="Register" />
    </fieldset>
}

The HTML helper in this case is BeginForm() and it is different somehow.. yes, it allows you to add HTML content in between the braces. Nice! Ever wondered how it’s done? Well, stop wondering.. let’s create our own. You basically need do create a class that inherits from IDisposable like so:

C#
public class AccordionBuilder<TModel>
{
    protected readonly TextWriter textWriter;
    protected readonly HtmlHelper<TModel> htmlHelper;

    internal AccordionBuilder(HtmlHelper<TModel> htmlHelper, Accordion accordion)
    {
	this.htmlHelper = htmlHelper;
	this.textWriter = htmlHelper.ViewContext.Writer;
        	this.textWriter.Write(@"<div class=""acccordion"">");
    }

    public override void Dispose()
    {
        this.textWriter.Write(@"</div>");
    }
}

The code for the real accordion is a little more complex than the above. I have simplified the above to give you a clearer picture of what’s going on. Basically, in the constructor we write the start of the element (a <div> in this case or <form> tag in the case of Html.BeginForm()) and in the Dispose() method we write the end tag. Since the using statement automatically calls Dispose() on an IDisposable, then that’s all we need to do.. nothing too fancy here.

Final word

These helpers are there to benefit everyone. As such it is my hope that there will be those who’d like to contribute and make these helpers even better for everyone. Enjoy!

Acknowledgements

I must give credit to Attila Losonc of the jQuery UI Helpers project; it is that awesome project that inspired me to create the Bootstrap Helpers.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Freelancer
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

Discussions on this specific version of this article. Add your comments on how to improve this article here. These comments will not be visible on the final published version of this article.