0

I'm trying to add some custom CSS to an MVC drop down list in order to change the appearance and animate it, which is all done using the classes. If I use a fixed list of items hard-coded in the page it works fine, but I can't figure out how to get the values to show up from the DropDownListFor. Here are three examples (using the 'User Level' dropdown on this particular form):

This one works but looks bad:

<div class="form-group">
    @Html.LabelFor(model => model.RoleID, "User Level", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
         @Html.DropDownListFor(model => model.RoleID, (SelectList)ViewBag.Roles, new { @Style = "width:290px", @tabindex = "13" })
         @Html.ValidationMessageFor(model => model.RoleID, "", new { @class = "text-danger" })
    </div>
</div>

This one looks and behaves how I want it to but only with fixed values:

<div class="form-group">
    <div class="control-label col-md-2">User Level</div>
    <div class="col-md-10">
        <div class="btn-group m-b-5">
            <button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown">Please select a user level</button>
            <ul class="dropdown-menu animated flipInX">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li class="divider"></li>
                <li><a href="#">Separated link</a></li>
            </ul>
        </div>
    </div>
</div>

This one I've tried to combine the two and it doesn't show anything in the dropdown when clicked, but looks correct on the page. The drop down isn't empty, there is simply nothing displayed at all when clicked:

<div class="form-group">
    @Html.LabelFor(model => model.RoleID, "User Level", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        <div class="btn-group m-b-5">
            <button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown">Please select a user level
                @Html.DropDownListFor(model => model.RoleID, (SelectList)ViewBag.Roles, new { @class = "dropdown-menu animated flipInX", @tabindex = "13" })
            </button>
                @Html.ValidationMessageFor(model => model.RoleID, "", new { @class = "text-danger" })
        </div>
    </div>
</div>

Have I missed something blindingly obvious or made a simple mistake? I'm pretty new to MVC/Razor.

Here's how they look on the page:

enter image description here

Thanks

UPDATE:

The third one renders as this:

    <div class="form-group">
            <label class="control-label col-md-2" for="RoleID">User Level</label>
            <div class="col-md-10">
                <div class="btn-group m-b-5">
                    <button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown">Please select a user level
                        <select class="dropdown-menu animated flipInX" id="RoleID" name="RoleID" tabindex="13"><option value="1">Internal</option>
<option value="2">External</option>
<option value="3">Administrator</option>
</select>
                    </button>
                        <span class="field-validation-valid text-danger" data-valmsg-for="RoleID" data-valmsg-replace="true"></span>
                </div>
            </div>
        </div>
5
  • What html is rendered on the third one? Commented Dec 10, 2015 at 21:29
  • @RobC Excellent question! I've updated the question with the results, I'm almost ashamed that I didn't think of including that... Commented Dec 10, 2015 at 21:43
  • You're obviously using bootstrap. Why not use a bootstrap dropdown instead, and skip the DropDownListFor? Commented Dec 10, 2015 at 21:49
  • @Patrick How would I do that and populate the list? Sorry for being stupid, I'm usually only dealing with static HTML. Would that option also allow me to add the classes that enable the animation? Thanks :) Commented Dec 10, 2015 at 21:54
  • Either iterate through ViewBag.Roles to generate each list item, or create a partial view with the same name as the class/type of each "role" and then use the Html.EditorFor() helper. Commented Dec 10, 2015 at 22:05

1 Answer 1

2

You can generate a helper.

namespace YourApp.Helpers
{
    public static class DropDownListExtensions
    {
        public static MvcHtmlString YourDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string text, IEnumerable<SelectListItem> listItems)
        {
            StringBuilder htmlBuilder = new StringBuilder("<div class=\"btn-group\">");
            htmlBuilder.Append("<button type=\"button\" class=\"btn btn-sm dropdown-toggle\" data-toggle=\"dropdown\">");
            htmlBuilder.Append(text).Append("</button>");
            htmlBuilder.Append("<input type=\"hidden\" name=\"");
            htmlBuilder.Append(((MemberExpression)expression.Body).Member.Name).Append("\">");
            htmlBuilder.Append("<ul class=\"dropdown-menu animated flipInX\">");
            foreach (var item in listItems)
            {
                htmlBuilder.Append("<li><a href=\"#\">").Append(item.Text).Append("</a></li>");
            }
            htmlBuilder.Append("</ul></div>");

            return new MvcHtmlString(htmlBuilder.ToString());
        }
    }
}

and you use

@Html.YourDropDownListFor(m => m.Property, "button text", listElements)

Just need to put the selected value <input type="hidden"> with javascript to work fully.

luck

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.