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.