net.js文件内容:
var net = new Object();
net.ContentLoader = function(url,postback,params)
{
this.url = url;
this.postback = postback;
this.params = params;
this.req = null;
this.loadXMLDoc(url);
}
net.ContentLoader.prototype =
{
createXMLHttpRequest:function()
{
if(window.XMLHttpRequest)
{
this.req = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
var arrVersions = ["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
for(var i = 0;i< arrVersions.length;i++)
{
try
{
this.req = new ActiveXObject(arrVersions[i]);
}
catch(oError)
{ }
}
}
return this.req;
},
loadXMLDoc:function(url)
{
if(this.createXMLHttpRequest())
{
try
{
var oThis = this;
this.req.onreadystatechange = function()
{
oThis.onReadyState.call(oThis);
//loader.onReadyState();
}
this.req.open("post",url,true);
this.req.setRequestHeader("Content-type","application/x-www-form-urlencoded");
this.req.send(this.params);
}
catch(oError)
{}
}
},
onReadyState:function()
{
if(this.req.readyState == 4)
{
if(this.req.status == 200 || this.req.status == 0 )
{
this.postback.call(this);
//this.postback();
}
}
}
}
main.js文件内容:
window.onload = function()
{
var elemSpan = document.createElement("Span");
elemSpan.id = "spanOutput";
elemSpan.className = "spanTextDropdown";
document.body.appendChild(elemSpan);
document.Form1.txtUserInput.obj = SetProperties(document.Form1.txtUserInput,document.Form1.txtUserValue,
"typeAheadData.aspx",true,true,true,true,
"无匹配数据!",false,null);
}
function SetProperties(xElem,xHidden,xserverCode,xignoreCase,xmatchAnywhere,
xmatchTextBoxWidth,xshowNoMatchMessage,xnoMatchingDataMessage,
xuseTimeout,xtheVisibleTime)
{
var props=
{
elem:xElem,
hidden:xHidden,
serverCode:xserverCode,
regExFlags:((xignoreCase)?"i":""),
regExAny:((xmatchAnywhere)?"":"^"),
matchAnywhere:xmatchAnywhere,
matchTextBoxWidth:xmatchTextBoxWidth,
theVisibleTime:xtheVisibleTime,
showNoMatchMessage:xshowNoMatchMessage,
noMatchingDataMessage:xnoMatchingDataMessage,
useTimeout:xuseTimeout
};
AddHandler(xElem);
return props;
}
var isOpera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
function AddHandler(objText)
{
objText.onkeyup = GiveOptions;
objText.onblur = function()
{
if(this.obj.useTimeout)
{
StartTimeout();
}
}
if(isOpera)
{
objText.onkeypress = GiveOptions;
}
}
//全局变量
var arrOptions = new Array();
var strLastValue = "";
var bMadeRequest;
var theTextBox;
var objLastActive;
var currentValueSelected = -1;
var bNoResults = false;
var isTiming = false;
function GiveOptions(event)
{
var iKey = -1;
if(window.event)
{
iKey = window.event.keyCode;
theTextBox = window.event.srcElement;
}
else
{
iKey = event.which;
theTextBox = event.target;
}
if(theTextBox.obj.useTimeout)
{
if(isTiming)
{
EraseTimeout();
}
StartTimeout();
}
if(theTextBox.value.length == 0 && !isOpera)
{
HideTheBox();
strLastValue = "";
return false;
}
if(objLastActive == theTextBox)
{
if(iKey == 13)
{
GrabHighlighted();
theTextBox.blur();
return false;
}
else if(iKey == 38)
{
MoveHighlight(-1);
return false;
}
else if(iKey == 40)
{
MoveHighlight(1);
return false;
}
}
//查询思想:
//1、如果此次查询的内容只是在上次的文本后面加了一些内容,则先判断如果上次查询有结果,
// 则从缓存中提取结果;如果缓冲之中没有结果,则向服务器发送请求。
//2、如果上次查询已无结果,并且此次输入内容也只是在上次的文本后面加入了内容,则不予处理;
//3、其它的情况下则向服务器提交请求,获取新的数据。
if((theTextBox.value.indexOf(strLastValue) == 0)&&(strLastValue !=""))
{
if(!bNoResults)
{
BuildList(theTextBox.value);
if(bNoResults)
{
objLastActive =theTextBox;
bMadeRequest = true;
TypeAhead(theTextBox.value);
}
}
}
else
{
objLastActive =theTextBox;
bMadeRequest = true;
TypeAhead(theTextBox.value);
}
//显示信息
ShowMessage();
strLastValue = theTextBox.value;
}
function TypeAhead(xStrText)
{
var strParams = "q="+xStrText+"&where="+theTextBox.obj.matchAnywhere;
var loader = new net.ContentLoader(theTextBox.obj.serverCode,BuildChoices,strParams);
}
function BuildChoices()
{
var strText = this.req.responseText;
eval(strText);
BuildList(strLastValue);
bMadeRequest = false;
}
function BuildList(theText)
{
SetElementPosition(theTextBox);
var theMatches = MakeMatches(theText);
theMatches = theMatches.join().replace(//,/gi,"");
if(theMatches.length > 0)
{
document.getElementById("spanOutput").innerHTML = theMatches;
document.getElementById("optionsList_0").className = "spanHighElement";
currentValueSelected = 0;
bNoResults = false;
}
else bNoResults = true;
}
function ShowMessage()
{
if(bNoResults)
{
currentValueSelected = -1;
bNoResults = true;
if(theTextBox.obj.showNoMatchMessage)
{
document.getElementById("spanOutput").innerHTML =
"<span class='noMatchData'>"+theTextBox.obj.noMatchingDataMessage + "</span>";
}
else HideTheBox();
}
}
function SetElementPosition(theTextBoxInput)
{
var selectedPosX = 0;
var selectedPosY = 0;
var theElement = theTextBoxInput;
if(!theElement) return;
var theElemHeight = theElement.offsetHeight;
var theElemWidth = theElement.offsetWidth;
while(theElement != null)
{
selectedPosX += theElement.offsetLeft;
selectedPosY += theElement.offsetTop;
theElement = theElement.offsetParent;
}
xPosElement = document.getElementById("spanOutput");
xPosElement.style.left = selectedPosX;
if(theTextBoxInput.obj.matchTextBoxWidth)
{
xPosElement.style.width = theElemWidth;
}
xPosElement.style.top = selectedPosY + theElemHeight;
xPosElement.style.display = "block";
if(theTextBoxInput.obj.useTimeout)
{
xPosElement.onmouseout = StartTimeout;
xPosElement.onmouseover = EraseTimeout;
}
else
{
xPosElement.onmouseout = null;
xPosElement.onmouseover = null;
}
}
var countForId = 0;
function MakeMatches(xCompareStr)
{
countForId = 0;
var matchArray = new Array();
var regExp = new RegExp(theTextBox.obj.regExAny + xCompareStr,theTextBox.obj.regExFlags);
for(var i = 0;i<arrOptions.length;i++)
{
var theMatch = arrOptions[i][0].match(regExp);
if(theMatch)
{
matchArray[matchArray.length] = CreateUnderline(arrOptions[i][0],xCompareStr,i);
}
}
return matchArray;
}
var undeStart = "<span class='spanMatchText'>";
var undeEnd = "</span>";
var selectSpanStart = "<span style='width:100%;display:block;' class = 'spanNormalElement'"+
"onmouseover='SetHighColor(this)'";
var selectSpanEnd = "</span>";
function CreateUnderline(xStr,xTextMatch,xVal)
{
selectSpanMid = "onclick='SetText("+xVal+")'"+"id='OptionsList_"+countForId+"'theArrayNumber='"+xVal+"'>";
var regExp = new RegExp(theTextBox.obj.regExAny+xTextMatch,theTextBox.obj.regExFlags);
var aStart = xStr.search(regExp);
var matchedText = xStr.substring(aStart,aStart+xTextMatch.length);
countForId++;
return selectSpanStart + selectSpanMid + xStr.replace(regExp,undeStart + matchedText + undeEnd )+selectSpanEnd;
}
function MoveHighlight(xDir)
{
if(currentValueSelected >= 0)
{
newValue = parseInt(currentValueSelected)+parseInt(xDir);
if(newValue > -1 && newValue < countForId)
{
currentValueSelected = newValue;
SetHighColor(null);
}
}
}
function SetHighColor(theTextBox)
{
if(theTextBox)
{
currentValueSelected = theTextBox.id.slice(theTextBox.id.indexOf("_") + 1,theTextBox.id.length);
}
for(var i = 0;i<countForId;i++)
{
document.getElementById("OptionsList_"+i).className = "spanNormalElement";
}
document.getElementById("OptionsList_"+currentValueSelected).className = "spanHighElement";
}
function SetText(xVal)
{
theTextBox.value = arrOptions[xVal][0];
theTextBox.obj.hidden.value = arrOptions[xVal][1];
document.getElementById("spanOutput").style.display = "none";
currentValueSelected = -1;
}
function GrabHighlighted()
{
if(currentValueSelected >= 0 )
{
xVal = document.getElementById("OptionsList_"+currentValueSelected).getAttribute("theArrayNumber");
SetText(xVal);
HideTheBox();
}
}
function HideTheBox()
{
document.getElementById("spanOutput").style.display = "none";
currentValueSelected = -1;
EraseTimeout();
}
function EraseTimeout()
{
clearTimeout(isTiming);
isTiming =false;
}
function StartTimeout()
{
isTiming = setTimeout("HideTheBox()",theTextBox.obj.theVisibleTime);
}
homepage.htm文件内容:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Ajax自动完成文本框实例</title>
<link rel="stylesheet" href="main.css" />
<script type="text/javascript" src="net.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<form name="Form1" AUTOCOMPLETE="off" id="Form1" action="" >
<label>自动完成文本框:</label><input type="text" name="txtUserInput" />
<input type="hidden" name="txtUserValue" id="hidden1" />
<input type="text" name="txtIgnore" style="display:none" />
</form>
</body>
</html>
typeAheadData.aspx.cs文件内容:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
public partial class typeAheadData : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "text/html";
string strQuery = Request.Form.Get("q").ToString();
string strAny = "";
if (Request.Form.Get("where").ToLower().Equals("true"))
{
strAny = "%";
}
string strSql = "select top 15 ProductName,ProductId from Products where ProductName " +
"like '"+ strAny + strQuery + "%" + "' order by ProductName";
DataTable dtQuestions = FillDataTable(strSql);
System.Text.StringBuilder strJSArr = new System.Text.StringBuilder();
strJSArr.Append( "arrOptions = new Array(" );
int iCount = 0;
int a = dtQuestions.Rows.Count;
foreach (DataRow row in dtQuestions.Rows)
{
if (iCount > 0)
{
strJSArr.Append(",");
}
strJSArr.Append("[");
strJSArr.Append("/"" + row["ProductName"].ToString() + "/",");
strJSArr.Append("/"" + row["ProductId"].ToString() + "/"");
strJSArr.Append("]");
iCount++;
}
strJSArr.Append(");");
Response.Write(strJSArr.ToString());
}
public DataTable FillDataTable(string strQuery)
{
string strConn = "server=localhost;database = Northwind;uid=sa;pwd=;";
DataSet ds = new DataSet();
new SqlDataAdapter(strQuery, strConn).Fill(ds);
return ds.Tables[0];
}
}
typeAheadData.aspx文件内容:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="typeAheadData.aspx.cs" Inherits="typeAheadData" %>
main.css文件内容:
span.spanTextDropdown
{
position:absolute;
top:0px;
left:0px;
width:150px;
z-index:101;
background-color:#C0C0C0;
border:1px solid #000000;
padding-left:2px;
overflow:visible;
display:none;
}
span.spanMatchText
{
text-decoration:underline;
font-weight:bold;
}
span.spanNormalElement
{
background:#c0c0c0;
}
span.spanHighElement
{
background:#909AF4;
color:White;
cursor:pointer;
}
span.noMatchData
{
font-weight:bold;
color:#0000ff;
}