ASP.NET MVC Combo Box

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.