I am currently developing a SmartDropDownList that extends alot of functionality from the traditional ASP.NET drop down. Please see the following code.
Code Behind
using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Text; using System.Web; using System.Web.Script; using System.Web.UI; using System.Web.UI.WebControls; namespace SmartDropDownListControl { /// <summary> /// /// </summary> public class SmartDropDownList : ListBox, IScriptControl { private string _selectedText; /// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); _selectedText = string.Empty; if (Page.IsPostBack) { if (Items.Count > 0 && SelectedIndex >= 0) { _selectedText = SelectedItem.Text; } } else { Style["width"] = "auto"; Style["padding"] = "0 0 0 0"; } } /// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnPreRender(EventArgs e) { if (!this.DesignMode) { Attributes["onclick"] = "SmartDropDownList_OnClick('" + ClientID + "')"; Attributes["onchange"] = "SmartDropDownList_OnSelect('" + ClientID + "')"; Attributes["onblur"] = "SmartDropDownList_OnBlur('" + ClientID + "')"; ScriptManager sm = ScriptManager.GetCurrent(Page); if (sm == null) throw new HttpException("A ScriptManager control must exist on the current page."); sm.RegisterScriptControl(this); } } /// <summary> /// /// </summary> /// <param name="writer"></param> protected override void Render(HtmlTextWriter writer) { base.Render(writer); writer.Write("<script type='text/javascript'>var " + ClientID + "_ScriptManager = new SmartDropDownList('" + ClientID + "');</script>"); } /// <summary> /// /// </summary> /// <param name="writer"></param> public override void RenderControl(HtmlTextWriter writer) { writer.Write("<input id='" + ClientID + "_TextBox' name='" + ClientID + "$TextBox' type='text' value='" + _selectedText + "' readonly='true' style='height:15px;width:" + GetCssWidth() + ";margin:0 0 0 0;padding:0 0 0 0;font-size:8pt;' onclick='SmartDropDownList_ShowDropDown(\"" + ClientID + "\")' />"); writer.Write("<img id='" + ClientID + "_Go' alt='' src='" + Page.ClientScript.GetWebResourceUrl(GetType(), "SmartDropDownListControl.go1.gif") + "' style='margin:1px 0 0 0;cursor:pointer;' onclick='SmartDropDownList_ShowDropDown(\"" + ClientID + "\")' />"); if (!this.DesignMode) { writer.Write("<div id='" + ClientID + "_ListContainer' style='position:absolute;top:0px;left:0px;display:none;'>"); base.RenderControl(writer); writer.Write("</div>"); } } /// <summary> /// /// </summary> /// <returns></returns> private string GetCssWidth() { string width = "auto"; if (Width.Type == UnitType.Cm) { width = Width.Value.ToString() + "cm"; } else if (Width.Type == UnitType.Em) { width = Width.Value.ToString() + "em"; } else if (Width.Type == UnitType.Inch) { width = Width.Value.ToString() + "in"; } else if (Width.Type == UnitType.Mm) { width = Width.Value.ToString() + "mm"; } else if (Width.Type == UnitType.Percentage) { width = Width.Value.ToString() + "%"; } else if (Width.Type == UnitType.Pica) { width = Width.Value.ToString() + "pc"; } else if (Width.Type == UnitType.Pixel) { width = Width.Value.ToString() + "px"; } else if (Width.Type == UnitType.Point) { width = Width.Value.ToString() + "pt"; } return width; } #region IScriptControl Members /// <summary> /// /// </summary> /// <returns></returns> public IEnumerable<ScriptDescriptor> GetScriptDescriptors() { return new ScriptDescriptor[] { new ScriptControlDescriptor("SmartDropDownList", ClientID) }; } /// <summary> /// /// </summary> /// <returns></returns> public IEnumerable<ScriptReference> GetScriptReferences() { return new ScriptReference[] { new ScriptReference("SmartDropDownListControl.SmartDropDownList.js", "SmartDropDownListControl") }; } #endregion } }
Javascript Code
function SmartDropDownList(elementId) {
this._elementId = elementId;
}
function SmartDropDownList_ShowDropDown(elementId) {
var container = document.getElementById(elementId + '_ListContainer');
var textbox = document.getElementById(elementId + '_TextBox');
var listbox = document.getElementById(elementId);
if(container && textbox && listbox)
{
if(container.style.display == 'none')
{
if(listbox.selectedIndex == -1)
listbox.selectedIndex = 0;
var pos = SmartDropDownList_FindPos(textbox);
container.style.top = pos[1] + textbox.offsetHeight;
container.style.left = pos[0];
container.style.display = '';
if(listbox.offsetWidth < textbox.offsetWidth)
listbox.style.width = textbox.offsetWidth;
listbox.focus();
}
else
{
container.style.top = 0;
container.style.left = 0;
container.style.display = 'none';
}
}
}
function SmartDropDownList_OnClick(elementId)
{
var container = document.getElementById(elementId + '_ListContainer');
var textbox = document.getElementById(elementId + '_TextBox');
var listbox = document.getElementById(elementId);
if(container && textbox && listbox && listbox.options.length > 0)
{
textbox.value = listbox.options[listbox.selectedIndex].text;
container.style.top = 0;
container.style.left = 0;
container.style.display = 'none';
}
}
function SmartDropDownList_OnSelect(elementId)
{
var textbox = document.getElementById(elementId + '_TextBox');
var listbox = document.getElementById(elementId);
if(textbox && listbox && listbox.options.length > 0)
{
textbox.value = listbox.options[listbox.selectedIndex].text;
}
}
function SmartDropDownList_OnBlur(elementId)
{
var go = document.getElementById(elementId + '_Go');
var pos = SmartDropDownList_FindPos(go);
var evt = event;
if(evt.x < pos[0] || evt.x > pos[0] + go.offsetWidth || evt.y < pos[1] || evt.y > pos[1] + go.offsetHeight)
SmartDropDownList_OnClick(elementId);
}
function SmartDropDownList_FindPos(obj)
{
var curleft = curtop = 0;
if (obj.offsetParent)
{
do
{
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return [curleft,curtop];
}