This is an AutoCompleteTextBox that Teddy recently encapsulated. We know that ASP.NET's own TextBox also supports certain AutoComplete functions, but it relies on browser implementation and cannot specify custom AutoComplete candidates. The AutoCompleteTextBox listed in this article makes up for this shortcoming. Just set the AutoCompleteTextBox.AutoCompleteData property and pass a string[] to make the TextBox support custom candidates.
If there is no candidate matching the current input,the AutoComplete logic
will be the same as a normal TextBox;
If only one candidate matches the current input, it is automatically completed;
If more than one candidate matches the current input, the first candidate is automatically completed in the textbox and a popup box containing all candidates is popped up.
implementation source
code is compiled in VS2005, but in fact, almost no syntax that relies on 2.0 is used, and it can be compiled under vs2003 with minimal modifications.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace Ilungasoft.Framework.Web.UI.WebControls
{
[ToolboxData("<{0}:AutoCompleteTextBox runat=server></{0}:AutoCompleteTextBox>")]
public class AutoCompleteTextBox : WebControl
{
Private Members#region Private Members
private TextBox textBox = new TextBox();
private HtmlGenericControl autoCompleteFrame = new HtmlGenericControl();
private string ToJsStringArray(params string[] strs)
{
if (strs != null && strs.Length > 0)
{
StringBuilder sb = new StringBuilder();
sb.Append(" new Array(");
foreach (string str in strs)
{
sb.Append(string.Format("'{0}', ", str.Replace("'", " \' ")));
}
return sb.ToString().TrimEnd(',', ' ') + ");";
}
else
{
return "new Array;";
}
}
private string MakeUniqueID(string id)
{
if (id != null && id.Trim().Length > 0)
{
return string.Concat(this.UniqueID.Replace("$", "_"), "_", id);
}
else
{
return this.UniqueID.Replace("$", "_");
}
}
#endregion
Properties#region Properties
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
if (Page.IsPostBack)
{
textBox.Text = Page.Request.Form[MakeUniqueID("textBox")];
}
return textBox.Text;
}
set
{
textBox.Text = value;
}
}
[Bindable(true)]
[Category("Behavior")]
[DefaultValue("")]
[Localizable(true)]
public int MaxLength
{
get
{
return textBox.MaxLength;
}
set
{
textBox.MaxLength = value;
}
}
[Bindable(true)]
[Category("Behavior")]
[DefaultValue(false)]
[Localizable(true)]
public bool ReadOnly
{
get
{
return textBox.ReadOnly;
}
set
{
textBox.ReadOnly = value;
}
}
public string[] AutoCompleteData
{
get
{
string[] s = (string[])ViewState["AutoCompleteData"];
return ((s == null) ? null : s);
}
set
{
ViewState["AutoCompleteData"] = value;
}
}
#endregion
Overriden Members#region Overriden Members
protected override void CreateChildControls()
{
create textBox#region create textBox
textBox.ID = MakeUniqueID("textBox");
textBox.AutoCompleteType = AutoCompleteType.Disabled;
textBox.Attributes.Add("onkeypress", string.Format("return __DoAutoComplete(event, '{0}')", MakeUniqueID(null)));
textBox.Attributes.Add("onblur", string.Format("if (!document.show_{0}) document.getElementById('{1}').style.display = 'none';", MakeUniqueID(null) , MakeUniqueID("autoCompleteFrame")));
textBox.Width = Width;
#endregion
create autoCompleteFrame#region create autoCompleteFrame
autoCompleteFrame.TagName = "iframe";
autoCompleteFrame.ID = MakeUniqueID("autoCompleteFrame");
autoCompleteFrame.Attributes.Add("style", "display:none; position: absolute; border: ridge 1px");
autoCompleteFrame.Attributes.Add("frameborder", "0");
autoCompleteFrame.Attributes.Add("marginheight", "0");
autoCompleteFrame.Attributes.Add("marginwidth", "2");
autoCompleteFrame.Attributes.Add("scrolling", "auto");
autoCompleteFrame.Attributes.Add("width", Width.ToString());
autoCompleteFrame.Attributes.Add("height", "100px");
autoCompleteFrame.Attributes.Add("src", "javascript:''");
autoCompleteFrame.Attributes.Add("onmouseover", string.Format("document.show_{0} = true;", MakeUniqueID(null)));
autoCompleteFrame.Attributes.Add("onmouseout", string.Format("document.show_{0} = false;", MakeUniqueID(null)));
#endregion
}
protected override void OnPreRender(EventArgs e)
{
Register Client Script Block#region Register Client Script Block
if (!Page.ClientScript.IsClientScriptBlockRegistered("__DoAutoComplete"))
{
string script = string.Concat(
"<script language="javascript" type="text/javascript">rn",
" var isOpera = navigator.userAgent.indexOf('Opera') > -1;rn",
" var isIE = navigator.userAgent.indexOf('MSIE') > 1 && !isOpera;rn",
" var isMoz = navigator.userAgent.indexOf('Mozilla/5.') == 0 && !isOpera;rn",
"rn",
" function textboxSelect (oTextbox, iStart, iEnd)rn",
" {rn",
" switch(arguments.length) {rn",
"case 1:rn",
" oTextbox.select();rn",
" break;rn",
"rn",
"case 2:rn",
" iEnd = oTextbox.value.length;rn",
" /* falls through */rn",
" rn",
" case 3: rn",
" if (isIE) {rn",
"var oRange = oTextbox.createTextRange();rn",
" oRange.moveStart("character", iStart);rn",
" oRange.moveEnd("character", -oTextbox.value.length + iEnd); rn",
" oRange.select(); rn",
" } else if (isMoz){rn",
" oTextbox.setSelectionRange(iStart, iEnd);rn",
" } rn",
" }rn",
"rn",
" oTextbox.focus();rn",
" }rn",
"rn",
" function textboxReplaceSelect (oTextbox, sText)rn",
" {rn",
" if (isIE) {rn",
"var oRange = document.selection.createRange();rn",
" oRange.text = sText;rn",
" oRange.collapse(true);rn",
" oRange.select(); rn",
" } else if (isMoz) {rn",
"var iStart = oTextbox.selectionStart;rn",
" oTextbox.value = oTextbox.value.substring(0, iStart) + sText + oTextbox.value.substring(oTextbox.selectionEnd, oTextbox.value.length);rn",
" oTextbox.setSelectionRange(iStart + sText.length, iStart + sText.length);rn",
" }rn",
"rn",
" oTextbox.focus();rn",
" }rn",
"rn",
" function autocompleteMatch (sText, arrValues)rn",
" {rn",
" var retMatches = ""; rn",
" rn",
" for (var i=0; i < arrValues.length; i++)rn",
" {rn",
" if (arrValues[i].indexOf(sText) == 0)rn",
" {rn",
" retMatches += arrValues[i] + ',';rn",
" }rn",
" }rn",
" rn",
" if (retMatches.length > 0)rn",
" {rn",
" retMatches = retMatches.substr(0, retMatches.length - 1);rn",
" } rn",
"rn",
" return retMatches;rn",
" }rn",
"rn",
" function __DoAutoComplete(oEvent, id)rn",
" {rn",
" var oTextbox = document.getElementById(id + '_textBox');rn",
" var frame = document.getElementById(id + '_autoCompleteFrame');rn",
" var arrValues = document[id + '_data'];rn",
" rn",
" switch (oEvent.keyCode) rn",
" {rn",
" case 38: //up arrow rn",
"case 40: //down arrowrn",
"case 37: //left arrowrn",
"case 39: //right arrowrn",
" case 33: //page up rn",
" case 34: //page down rn",
" case 36: //home rn",
" case 35: //end rn",
" case 13: //enter rn",
" case 9: //tab rn",
" case 27: //esc rn",
" case 16: //shift rn",
" case 17: //ctrl rn",
" case 18: //alt rn",
"case 20: //caps lockrn",
" case 8: //backspace rn",
"case 46: //deletern",
" return true;rn",
" break;rn",
" rn",
"default:rn",
" textboxReplaceSelect(oTextbox, String.fromCharCode(isIE ? oEvent.keyCode : oEvent.charCode));rn",
" var iLen = oTextbox.value.length;rn",
"rn",
" var sMatches = autocompleteMatch(oTextbox.value, arrValues);rn",
"rn",
" if (sMatches.length > 0)rn",
" {rn",
"var arrMatches = sMatches.split(',');rn",
" oTextbox.value = arrMatches[0];rn",
" textboxSelect(oTextbox, iLen, oTextbox.value.length);rn",
" rn",
" if (arrMatches.length > 1)rn",
" {rn",
" frame.style.display = 'inline';rn",
" frame.height = '100';rn",
" rn",
" frame.contentWindow.document.body.innerHTML = '';rn",
" for (var i = 0; i < arrMatches.length; i++)rn",
" {rn",
" frame.contentWindow.document.body.innerHTML += '<div style="width: 100%; cursor: default" onmouseover="this.style.backgroundColor=\'#316AC5\'; this. style.color=\'white\';" onmouseout="this.style.backgroundColor=\'\'; this.style.color=\'black\';" onclick= "parent.document.getElementById( \'' + id + '_textBox\').value = this.innerHTML">' + arrMatches[i] + '</div>';rn",
" }rn",
" rn",
" frame.contentWindow.document.body.style.backgroundColor = 'white';rn",
" frame.contentWindow.document.onclick = function() { document.getElementById(id + '_autoCompleteFrame').style.display = 'none'; };rn",
" } rn",
" } rn",
" rn",
" return false;rn",
" } rn",
" }rn",
"</script>rn",
"");
Page.ClientScript.RegisterClientScriptBlock(typeof(string), "__DoAutoComplete", script);
}
if (!Page.ClientScript.IsClientScriptBlockRegistered(MakeUniqueID("data")))
{
Page.ClientScript.RegisterClientScriptBlock(typeof(string), MakeUniqueID("data"), string.Format("<script language="javascript" type="text/javascript">document.{0}_data = { 1}</script>", MakeUniqueID(null), ToJsStringArray(AutoCompleteData)));
}
#endregion
}
protected override void RenderContents(HtmlTextWriter output)
{
output.WriteLine(string.Format("<div onmouseleave="document.getElementById('{0}').style.display = 'none';" style="width:{1}" >", MakeUniqueID("autoCompleteFrame"), Width));
textBox.RenderControl(output);
output.WriteLine("<br />");
autoCompleteFrame.RenderControl(output);
output.WriteLine("</div>");
}
#endregion
}
}
download