Reputation: 1447
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:
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>
Upvotes: 0
Views: 1175
Reputation: 344
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
Upvotes: 2