One problem with developing both windows and web applications, is sometimes a client asks for a simple WinForms control that is in their windows application and they want to use the same control on their website. I've found one of the most common requests is a Combo Box. Of course the HTML specification doesn't support Combo Boxes, alternatives include a combination of funky looking plugins. I wanted to have a simple and native looking combo box. After a while of searching, I found this page http://bit.wisestamp.com/uncategorized/htmljquery-editable-combo-2/ which shows how to use a bit of simple jQuery and CSS to achive the desired effect.
This is the code:
<select id="combo" style="width: 200px;" onchange="$('input#text').val($(this).val());"> <option>option 1</option> <option>option 2</option> <option>option 3</option> </select> <input id="text" style="margin-left: -203px; width: 180px; height: 1.2em; border: 0;" />
After using this a few times in ASP.NET MVC, I thought it would be best to use it as you would a standard MVC control. Similar to that of Html.DropDownList and Html.DropDownListFor but with the ability to type into the drop down list.
You can create an extension using the following methods:
public static MvcHtmlString ComboBox(this HtmlHelper html, string name, SelectList items, string selectedValue) { StringBuilder sb = new StringBuilder(); sb.Append(html.DropDownList(name + "_hidden", items, new { @style = "width: 200px;", @onchange = "$('input#" + name + "').val($(this).val());" })); sb.Append(html.TextBox(name, selectedValue, new { @style = "margin-left: -199px; width: 179px; height: 1.2em; border: 0;" })); return MvcHtmlString.Create(sb.ToString()); } public static MvcHtmlString ComboBoxFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, SelectList items) { MemberExpression me = (MemberExpression)expression.Body; string name = me.Member.Name; StringBuilder sb = new StringBuilder(); sb.Append(html.DropDownList(name + "_hidden", items, new { @style = "width: 200px;", @onchange = "$('input#" + name + "').val($(this).val());" })); sb.Append(html.TextBoxFor(expression, new { @style = "margin-left: -199px; width: 179px; height: 1.2em; border: 0;" })); return MvcHtmlString.Create(sb.ToString()); }
And then call these new methods using the following:
<%: Html.ComboBox("Category", selectListVariable, selectedValue) %> <%: Html.ComboBoxFor(model => model.Category, selectListVariable)) %>
As you can see, it works exactly the same as Html.DropDownList. You could do a bit more work to extend it to do other things.