johnllao

September 15, 2009

SmartDropDownList

Filed under: Uncategorized — johnllao @ 9:58 pm

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];
}

Blog at WordPress.com.