Shuvo Amin Shuvo Amin - 3 months ago 38
ASP.NET (C#) Question

Bootstrap Tab Inside ASP.Net Razor Loop

I have simple bootstrap(3) tabs inside a

div
(
class="example"
).

I have the
div
saved in a Partial view.

I am using
foreach
loop in my Razor view, passing the object to the Partial view and outputting it for each iteration.

How can I simply navigate each
div
's own tabs without affecting other tabs inside the loop?

View:-

@foreach (var pbrModel in Model)
{
@Html.Partial("~/_TestViewPartial.cshtml", pbrModel)
}


Partial View:-

@model PbrViewModel

<div class="example">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="active"><a href="#home" data-toggle="tab">Home</a></li>
<li><a href="#profile" data-toggle="tab">Profile</a></li>
<li><a href="#messages" data-toggle="tab">Messages</a></li>
<li><a href="#settings" data-toggle="tab">Settings</a></li>
</ul>

<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home">...</div>
<div class="tab-pane" id="profile">...</div>
<div class="tab-pane" id="messages">...</div>
<div class="tab-pane" id="settings">...</div>
</div>
</div>

Answer

You can use a for loop to iterate over the items in your main view's Model, and then use the i iterator to make each tab's id unique by appending it in the partial view.

You can pass the i value as a "model" to the partial view when you iterate.

Like so:

@for (var i = 0; i < Model.Count; i++)
{
    @Html.Partial("~/_TestViewPartial.cshtml", i)
}

Then in the partial view, you can use the "model" passed to it from your for loop - in this case as an int type, so it can print the value into the ids accordingly.

Like so:

@model int

<div class="example">

    <!-- Nav tabs -->
    <ul class="nav nav-tabs">
        <li class="active"><a href="#home@Model" data-toggle="tab">Home</a></li>
        <li><a href="#profile@Model" data-toggle="tab">Profile</a></li>
        <li><a href="#messages@Model" data-toggle="tab">Messages</a></li>
        <li><a href="#settings@Model" data-toggle="tab">Settings</a></li>
    </ul>

    <!-- Tab panes -->
    <div class="tab-content">
        <div class="tab-pane active" id="home@Model">...</div>
        <div class="tab-pane" id="profile@Model">...</div>
        <div class="tab-pane" id="messages@Model">...</div>
        <div class="tab-pane" id="settings@Model">...</div>
    </div>

</div>

Much like my previous (before this edit) answer, passing the i variable to each iteration ensures the ids are unique.

Unfortunately, with this way you will not be able to access any properties of the main view's Model, as you are only passing the int to the Partial view, and nothing else (I explain more below).


A couple of notes to think about:

  • Your path to the partial doesn't need to be "relatively absolute". In that, I mean you can just use "_TestViewPartial.cshtml" as the first argument (omitting the "~/")
  • If you do wish to access properties of your main view's pbrModels inside the partial, you will need to pass these to the partial (as per your OP, with PbrViewModel as the @model type) and I would suggest adding a unique indexer property to that type, if possible - so you can then print this in the id/href of the elements within your partial view, like in my example; just use @model.MyUniqueIDProperty or whatever friendly name you have for it
  • THINK - Do you really need a separate partial view for this? If you're reusing the code elsewhere, then yes. If it's solely for the purpose of the page, then no; I would defer to having the code in the main view's code - you would then still be able to access the main Model of the page, if you need to get properties from the PbrViewModels using the indexer you're at (Model[i])

Any questions, just ask.

Hope this helps! :)