How to apply Bootstrap dropdown style to an ASP.NET MVC DropDownList?
Asked Answered
R

8

42

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:

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:

image

Question: Is it possible to get the same look and feel when using @Html.DropDownList as when using the HTML code from MVC?

Ruano answered 24/10, 2014 at 20:10 Comment(2)
Extension method similar to Html.DropDownList will help to create desired HTML output.Numinous
I took the same code and it doesn't work with me. I included bootstrap in the <head> tag and added the followin code: <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> </ul> </div> Do you know why?Foggy
A
55

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.

enter image description here

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>

}
Av answered 24/10, 2014 at 20:38 Comment(9)
I always try and to include a code sample if possible however in this instance I was pressed for time. If a code sample would help you out then I'd be happy to put one together and update the answer for you?Av
I honestly don't mind following the link and getting it myself but I do think adding the code would be helpful for others.Anstus
@ᴉʞuǝ I've updated my answer to provide a code sample. A little late, but better late than never!Av
Much better, if you had some erratic voting on this after your edit that was me, was trying to remove my downvote via the mobile app and it was giving me trouble. +1 now thoughAnstus
No problem, thanks for taking the time to remove your down vote so long after I answered!Av
TYVM for the great answer! I posted a followup question here: #41317839Willamina
@JosephWoodward thank you for your effort! Your code sample is helpful.Chyou
@UğurAldanmaz Not a problem, glad it was useful!Av
This answer is old. Check @Ahmad Aghazadeh answerPastorate
W
58

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"})
Weatherwise answered 9/9, 2015 at 7:18 Comment(3)
I respectfully disagree. Adding a form-control class will simply create a native, semi-styled drop down that the OP said he would like to avoid. I've updated my answer with a working sample.Av
How can you create drop-up menu with razor?Tefillin
This works good. Note that the pre-generated code might look like @Html.EditorFor(model => model.MovieGenreModel, new { htmlAttributes = new { @class = "form-control" } }) If you only change the Html.EditorFor to Html.DropDownListFor and put in your SelectList it won't work. You need to ensure you get rid of the new { htmlAttributes bit as well.Bargello
A
55

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.

enter image description here

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>

}
Av answered 24/10, 2014 at 20:38 Comment(9)
I always try and to include a code sample if possible however in this instance I was pressed for time. If a code sample would help you out then I'd be happy to put one together and update the answer for you?Av
I honestly don't mind following the link and getting it myself but I do think adding the code would be helpful for others.Anstus
@ᴉʞuǝ I've updated my answer to provide a code sample. A little late, but better late than never!Av
Much better, if you had some erratic voting on this after your edit that was me, was trying to remove my downvote via the mobile app and it was giving me trouble. +1 now thoughAnstus
No problem, thanks for taking the time to remove your down vote so long after I answered!Av
TYVM for the great answer! I posted a followup question here: #41317839Willamina
@JosephWoodward thank you for your effort! Your code sample is helpful.Chyou
@UğurAldanmaz Not a problem, glad it was useful!Av
This answer is old. Check @Ahmad Aghazadeh answerPastorate
C
8
@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();

Cribble answered 6/7, 2015 at 6:55 Comment(0)
S
3

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();
        }
    }
}
Sign answered 28/7, 2021 at 10:44 Comment(0)
B
1

Try this code :

  @Html.DropDownListFor(model => model.MovieGenreModel, SelectList,
                   new { @class = "form-control",aria_describedby="dropdownMenu1"})
Bedard answered 27/9, 2016 at 13:5 Comment(0)
I
0

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.

Identification answered 11/7, 2017 at 10:11 Comment(0)
C
0

After Logn Search I had to use JQuery to add class attribute dynamically as below:

$(document).ready(function(){
   $("select").last().addClass("form-control");
});
Coady answered 28/12, 2021 at 21:46 Comment(0)
A
-1

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}

Arnuad answered 6/7, 2016 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.