daveaglick / FluentBootstrap

Provides extensions, helper classes, model binding, and other goodies to help you use the Bootstrap CSS framework from .NET code.
http://www.fluentbootstrap.com
MIT License
200 stars 76 forks source link

How to create a tab-pane? #40

Closed jptillman closed 9 years ago

jptillman commented 9 years ago

The docs show how to create tabs, but not how to actually do anything useful with them. How does one create a tab-pane section and make it active with the tabs?

jptillman commented 9 years ago

Follow-up related question: tabs created with FB don't have "a" tags with the

aria-controls="home" role="tab" data-toggle="tab" 

attributes on them. Without this, how do I target a tab-panel for a data-toggle?

daveaglick commented 9 years ago

The kind of tabs you're talking about, where a content div changes based on the selected tab, are part of the Bootstrap JavaScript support (see here: http://getbootstrap.com/javascript/#tabs). FluentBootstrap doesn't have any native support for the Bootstrap JavaScript controls yet, though I hope to get to it one of these days (starting with modals, see #5). Right now, tabs can link to other pages, but not control a content div.

That said, FluentBootstrap was designed to be flexible and it's possible to make use of the Bootstrap JavaScript tabs with just a little extra code. The first thing to mention is that, in reference to your second comment, any fluent methods you apply to the tab will actually apply to the wrapped a element and not the outer li for this very reason. Therefore, you can write

@tabs.Tab("Home").SetActive().AddAttribute("aria-controls", "home")

and that will output

<li class="active">
    <a href="#" aria-controls="home">Home</a>
</li>

To replicate the example in the Bootstrap documentation, you would write

using (var tabs = Html.Bootstrap().Tabs().Begin())
{
    @tabs.Tab("Home", "#home").SetActive().AddAttribute("aria-controls", "home").AddAttribute("role", "tab").AddAttribute("data-toggle", "tab")
    @tabs.Tab("Profile", "#profile").AddAttribute("aria-controls", "profile").AddAttribute("role", "tab").AddAttribute("data-toggle", "tab")
    @tabs.Tab("Messages", "#messages").AddAttribute("aria-controls", "messages").AddAttribute("role", "tab").AddAttribute("data-toggle", "tab")
    @tabs.Tab("Settings", "#settings").AddAttribute("aria-controls", "settings").AddAttribute("role", "tab").AddAttribute("data-toggle", "tab")
}
using (Html.Bootstrap().Div().AddCss("tab-content").Begin())
{
    using (Html.Bootstrap().Div().SetId("home").AddCss("tab-pane", "active").AddAttribute("role", "tabpanel").Begin())
    {
        <text>This is the home tab.</text>
    }
    using (Html.Bootstrap().Div().SetId("profile").AddCss("tab-pane").AddAttribute("role", "tabpanel").Begin())
    {
        <text>This is the profile tab.</text>
    }
    using (Html.Bootstrap().Div().SetId("messages").AddCss("tab-pane").AddAttribute("role", "tabpanel").Begin())
    {
        <text>This is the messages tab.</text>
    }
    using (Html.Bootstrap().Div().SetId("settings").AddCss("tab-pane").AddAttribute("role", "tabpanel").Begin())
    {
        <text>This is the settings tab.</text>
    }
}

It's a little verbose, but it'll get the job done. You could always simplify further by creating a custom HtmlExtension that outputs the tabs and divs, that is until I get native support for the JavaScript widgets implemented and this gets much easier.