'How to apply Bootstrap dropdown style to an ASP.NET MVC DropDownList?
Given is the following MVC razor code which creates a dropdown from a list:
@Html.DropDownList("MyTestList", null, new { @class = "btn btn-default dropdown-toggle" })
This will create the following dropdown:
When using the code from getbootstrap.com:
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">test1</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">test2</a></li>
</ul>
</div>
It will show the dropdown like this:
Question:
Is it possible to get the same look and feel when using @Html.DropDownList
as when using the HTML code from MVC?
Solution 1:[1]
It's not possible to use Razor's @Html.DropDownList()
method to create the Bootstrap dropdown you've mentioned. Though it's easy enough to create your own HTML helper that renders the code necessary to create the aforementioned dropdown.
There are plenty of tutorials and guides (such as this one) that will take you through the process of creating a custom HTML Helper. They're really not that difficult to create and can really help speed up your development times and encourage code reuse.
Update:
Given the amount of attention this question is getting an the number of upvotes the (incorrect) answer below is getting, here is a long overdue (year and a half!) code sample with an image to demonstrate the differences.
You can copy and paste this code into your solution and it should work.
The code:
public class BootstrapHtml
{
public static MvcHtmlString Dropdown(string id, List<SelectListItem> selectListItems, string label)
{
var button = new TagBuilder("button")
{
Attributes =
{
{"id", id},
{"type", "button"},
{"data-toggle", "dropdown"}
}
};
button.AddCssClass("btn");
button.AddCssClass("btn-default");
button.AddCssClass("dropdown-toggle");
button.SetInnerText(label);
button.InnerHtml += " " + BuildCaret();
var wrapper = new TagBuilder("div");
wrapper.AddCssClass("dropdown");
wrapper.InnerHtml += button;
wrapper.InnerHtml += BuildDropdown(id, selectListItems);
return new MvcHtmlString(wrapper.ToString());
}
private static string BuildCaret()
{
var caret = new TagBuilder("span");
caret.AddCssClass("caret");
return caret.ToString();
}
private static string BuildDropdown(string id, IEnumerable<SelectListItem> items)
{
var list = new TagBuilder("ul")
{
Attributes =
{
{"class", "dropdown-menu"},
{"role", "menu"},
{"aria-labelledby", id}
}
};
var listItem = new TagBuilder("li");
listItem.Attributes.Add("role", "presentation");
items.ForEach(x => list.InnerHtml += "<li role=\"presentation\">" + BuildListRow(x) + "</li>");
return list.ToString();
}
private static string BuildListRow(SelectListItem item)
{
var anchor = new TagBuilder("a")
{
Attributes =
{
{"role", "menuitem"},
{"tabindex", "-1"},
{"href", item.Value}
}
};
anchor.SetInnerText(item.Text);
return anchor.ToString();
}
}
Usage:
@using (Html.BeginForm("", "", FormMethod.Post))
{
var items = new List<SelectListItem>()
{
new SelectListItem() { Text = "Item 1", Value = "#" },
new SelectListItem() { Text = "Item 2", Value = "#" },
};
<div class="form-group">
@Html.Label("Before", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("Name", items, "Dropdown", new { @class = "form-control"})
</div>
</div>
<br/>
<br/>
<br/>
<div class="form-group">
@Html.Label("After", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@BootstrapHtml.Dropdown("dropdownMenu1", items, "Dropdown")
</div>
</div>
}
Solution 2:[2]
It is very much possible, and really easy. Please Read: DropDownList bootstrap styling
All you need is:
@Html.DropDownList("movieGenre", "All", new { @class = "form-control"})
or
@Html.DropDownListFor(model => model.MovieGenreModel, SelectList, new { @class = "form-control"})
Solution 3:[3]
@using (Html.BeginForm("Index", "ELibrary"))
{
@Html.DropDownListFor(m => m.Status, new SelectList(Model.StatusItems, "key", "value"), "-- Status --", new { onchange = "this.form.submit();", @class = "form-control" })
}
You just have to add @class="form-control" . It works fine. but I have also enclosed it in a Html.Begin form();
Solution 4:[4]
To whomever is looking for the .Net core implementation, I have adjusted the Joseph Woodward's answer as follows.
public class BootstrapHtml
{
public static HtmlString Dropdown(string id, List<SelectListItem> selectListItems, string label)
{
var button = new TagBuilder("button")
{
Attributes =
{
{"id", id},
{"type", "button"},
{"data-toggle", "dropdown"}
}
};
button.AddCssClass("btn");
button.AddCssClass("btn-default");
button.AddCssClass("dropdown-toggle");
//button.SetInnerText(label);
button.InnerHtml.Append(" " + label);
button.InnerHtml.AppendHtml(BuildCaret());
//button.InnerHtml += " " + BuildCaret();
var wrapper = new TagBuilder("div");
wrapper.AddCssClass("dropdown");
wrapper.InnerHtml.AppendHtml(button);
wrapper.InnerHtml.AppendHtml(BuildDropdown(id, selectListItems));
//wrapper.InnerHtml += button;
//wrapper.InnerHtml += BuildDropdown(id, selectListItems);
using (var writer = new System.IO.StringWriter())
{
wrapper.WriteTo(writer, HtmlEncoder.Default);
string asd = writer.ToString();
return new HtmlString(writer.ToString());
}
}
private static TagBuilder BuildCaret()
{
var caret = new TagBuilder("span");
caret.AddCssClass("caret");
return caret;
}
private static TagBuilder BuildDropdown(string id, IEnumerable<SelectListItem> items)
{
var list = new TagBuilder("ul")
{
Attributes =
{
{"class", "dropdown-menu"},
{"role", "menu"},
{"aria-labelledby", id}
}
};
var listItem = new TagBuilder("li");
listItem.Attributes.Add("role", "presentation");
foreach (var item in items)
{
list.InnerHtml.AppendHtml("<li role=\"presentation\">" + BuildListRow(item) + "</li>");
}
//items.ForEach(x => list.InnerHtml += "<li role=\"presentation\">" + BuildListRow(x) + "</li>");
return list;
}
private static string BuildListRow(SelectListItem item)
{
var anchor = new TagBuilder("a")
{
Attributes =
{
{"role", "menuitem"},
{"tabindex", "-1"},
{"href", item.Value}
}
};
var span = new TagBuilder("span");
span.InnerHtml.Append(item.Text);
anchor.InnerHtml.AppendHtml(span);
//anchor.SetInnerText(item.Text);
using (var writer = new System.IO.StringWriter())
{
anchor.WriteTo(writer, HtmlEncoder.Default);
string asd = writer.ToString();
return writer.ToString();
}
}
}
Solution 5:[5]
Try this code :
@Html.DropDownListFor(model => model.MovieGenreModel, SelectList,
new { @class = "form-control",aria_describedby="dropdownMenu1"})
Solution 6:[6]
I have got a bootstrap button working in ASP.net MVC with a real-life example that I am using at my current place of work.
<div class="dropdown" style="display:inline-block">
<button class="btn btn-warning dropdown-toggle" type="button" data-toggle="dropdown" value="@Model.Id" runat="server"><span class="glyphicon glyphicon-user"></span> Assign <span class="caret"></span></button>
<ul class="dropdown-menu" onclick="location.href='@Url.Action("AssignTicket", "Home", new {AssignId = Model.Id })'">
@foreach (var user in (IEnumerable<SelectListItem>)ViewBag.User)
{
<li>@user.Text</li>
}
</ul>
</div>
The View.user is getting the users name directly from the database. Jope this is what some of you were looking for.
Solution 7:[7]
After Logn Search I had to use JQuery to add class attribute dynamically as below:
$(document).ready(function(){
$("select").last().addClass("form-control");
});
Solution 8:[8]
Adding @class = "form-control"
doesn't work for @Html.DropDownListFor
. That being said you can mirror the styles of the other "form-control"
inputs by copying those styles (e.g. through Developer Tools) and then wrap the @Html.DropDownListFor
in a div
that you give an id (e.g. #my-selector
). Style the child of the div
, for example: #my-selector
> select { ...normal bootstrap form-control styles}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow