//Default.aspx 搜索文本框输入页面
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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 runat="server">
<title></title>
<script src="Scripts/autosuggest.js" type="text/javascript"></script>
<link href="Styles/search.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
window.onload = function () {
var oTextbox = new AutoSuggestControl(document.getElementById("txtSearchBox"), new SuggestionProvider());
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" id="txtSearchBox" odata="" class="sstxtbox" />
</div>
</form>
</body>
</html>
//SearchSuggest.aspx 页面提供XML数据源
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SearchSuggest.aspx.cs" Inherits="SearchSuggest" %>
<%= this.GetSuggestionXml() %>
//后台代码块
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
public partial class SearchSuggest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected List<string> GetSearchSuggistInfo()
{
string valString = Request.QueryString["keyword"];
if (string.IsNullOrWhiteSpace(valString))
{
return null;
}
else
{
valString = valString.Trim();
valString += "%";
List<string> strName = SortInfoManager.GetStudentNameBystrName(valString);//些方法从数据库获取数据源
return strName;
}
}
protected string GetSuggestionXml()
{
Response.ContentType = "text/xml";
StringBuilder xmlResult = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
List<string> nameList = GetSearchSuggistInfo();
if (nameList != null)
{
xmlResult.Append("<root>");
foreach (var str in nameList)
{
xmlResult.AppendFormat("<message>");
xmlResult.AppendFormat("<text>{0}</text>", str);
xmlResult.Append("</message>");
}
xmlResult.Append("</root>");
return xmlResult.ToString();
}
else
{
return null;
}
}
}
//autosuggest.js 脚本
/**
* An autosuggest textbox control.
* @class
* @scope public
*/
function AutoSuggestControl(oTextbox /*:HTMLInputElement*/,
oProvider /*:SuggestionProvider*/) {
/**
* The currently selected suggestions.
* @scope private
*/
this.cur /*:int*/ = -1;
/**
* The dropdown list layer.
* @scope private
*/
this.layer = null;
/**
* Suggestion provider for the autosuggest feature.
* @scope private.
*/
this.provider /*:SuggestionProvider*/ = oProvider;
/**
* The textbox to capture.
* @scope private
*/
this.textbox /*:HTMLInputElement*/ = oTextbox;
/**
* Timeout ID for fast typers.
* @scope private
*/
this.timeoutId /*:int*/ = null;
/**
* The text that the user typed.
* @scope private
*/
this.userText /*:String*/ = oTextbox.value;
this.odata = oTextbox.getAttribute("odata");
//initialize the control
this.init();
}
/**
* Autosuggests one or more suggestions for what the user has typed.
* If no suggestions are passed in, then no autosuggest occurs.
* @scope private
* @param aSuggestions An array of suggestion strings.
* @param bTypeAhead If the control should provide a type ahead suggestion.
*/
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/,
bTypeAhead /*:boolean*/) {
//re-initialize pointer to current suggestion
this.cur = -1;
//make sure there's at least one suggestion
if (!aSuggestions) {
this.hideSuggestions();
return;
}
var bSuggestions = aSuggestions.getElementsByTagName("message");
//alert(bSuggestions.length);
if (bSuggestions.length > 0) {
if (bTypeAhead) {
this.typeAhead(bSuggestions[0].getElementsByTagName("text")[0].firstChild.data);
}
this.showSuggestions(aSuggestions);
} else {
this.hideSuggestions();
}
};
/*function goSearchInfo(data) {
if (data) {
var turl = "SearchInfo.aspx?keyword=" + encodeURI(data);
window.location = turl;
}
}*/
/**
* Creates the dropdown layer to display multiple suggestions.
* @scope private
*/
AutoSuggestControl.prototype.createDropDown = function () {
//create the layer and assign styles
this.layer = document.createElement("div");
this.layer.className = "suggestions_F";
this.layer.style.visibility = "hidden";
this.layer.style.width = this.textbox.offsetWidth;
document.body.appendChild(this.layer);
//when the user clicks on the a suggestion, get the text (innerHTML)
//and place it into a textbox
var oThis = this;
this.layer.onmousedown =
this.layer.onmouseup =
this.layer.onmouseover = function (oEvent) {
oEvent = oEvent || window.event;
oTarget = oEvent.target || oEvent.srcElement;
if (oEvent.type == "mousedown") {
oThis.textbox.value = oTarget.firstChild.nodeValue;
oThis.hideSuggestions();
goSearchInfo(oTarget.firstChild.nodeValue);
} else if (oEvent.type == "mouseover") {
oThis.highlightSuggestion(oTarget);
} else {
oThis.textbox.focus();
}
};
};
/**
* Gets the left coordinate of the textbox.
* @scope private
* @return The left coordinate of the textbox in pixels.
*/
AutoSuggestControl.prototype.getLeft = function () /*:int*/{
var oNode = this.textbox;
var iLeft = 0;
while (oNode != document.body) {
iLeft += oNode.offsetLeft;
oNode = oNode.offsetParent;
}
return iLeft;
};
/**
* Gets the top coordinate of the textbox.
* @scope private
* @return The top coordinate of the textbox in pixels.
*/
AutoSuggestControl.prototype.getTop = function () /*:int*/{
var oNode = this.textbox;
var iTop = 0;
while (oNode != document.body) {
iTop += oNode.offsetTop;
oNode = oNode.offsetParent;
}
return iTop + 15;
};
/**
* Highlights the next or previous suggestion in the dropdown and
* places the suggestion into the textbox.
* @param iDiff Either a positive or negative number indicating whether
* to select the next or previous sugggestion, respectively.
* @scope private
*/
AutoSuggestControl.prototype.goToSuggestion = function (iDiff /*:int*/) {
var cSuggestionNodes = this.layer.childNodes;
if (cSuggestionNodes.length > 0) {
var oNode = null;
if (iDiff > 0) {
if (this.cur < cSuggestionNodes.length - 1) {
oNode = cSuggestionNodes[++this.cur];
}
} else {
if (this.cur > 0) {
oNode = cSuggestionNodes[--this.cur];
}
}
if (oNode) {
this.highlightSuggestion(oNode);
this.textbox.value = oNode.firstChild.nodeValue;
}
}
};
/**
* Handles three keydown events.
* @scope private
* @param oEvent The event object for the keydown event.
*/
AutoSuggestControl.prototype.handleKeyDown = function (oEvent /*:Event*/) {
switch (oEvent.keyCode) {
case 38: //up arrow
this.goToSuggestion(-1);
break;
case 40: //down arrow
this.goToSuggestion(1);
break;
case 27: //esc
this.textbox.value = this.userText;
this.selectRange(this.userText.length, 0);
/* falls through */
case 13: //enter
this.hideSuggestions();
oEvent.returnValue = false;
if (oEvent.preventDefault) {
oEvent.preventDefault();
}
break;
}
};
/**
* Handles keyup events.
* @scope private
* @param oEvent The event object for the keyup event.
*/
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
var iKeyCode = oEvent.keyCode;
var oThis = this;
//get the currently entered text
//for backspace (8) and delete (46), shows suggestions without typeahead
if (iKeyCode == 13) {
if (this.textbox.value) {
if (this.userText == this.textbox.value) {
// goSearchInfo(this.userText);
}
}
//var cControl = document.getElementById("txtSearchBox");
this.userText = this.textbox.value;
}
else {
this.userText = this.textbox.value;
clearTimeout(this.timeoutId);
if (iKeyCode == 8 || iKeyCode == 46) {
this.timeoutId = setTimeout(function () {
oThis.provider.requestSuggestions(oThis, false);
}, 250);
//make sure not to interfere with non-character keys
}
else if ((iKeyCode != 16 && iKeyCode < 32) || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
//ignore
} else {
//request suggestions from the suggestion provider with typeahead
if (!oThis.userText) {
//oThis.odata = String.fromCharCode(iKeyCode);
//oThis.textbox.setAttribute("odata", this.odata);
oThis.userText = String.fromCharCode(iKeyCode);
//alert(oThis.userText);
//oThis.setAttribute("aa", "aa");
}
this.timeoutId = setTimeout(function () {
oThis.provider.requestSuggestions(oThis, false);
}, 250);
}
}
};
/**
* Hides the suggestion dropdown.
* @scope private
*/
AutoSuggestControl.prototype.hideSuggestions = function () {
this.layer.style.visibility = "hidden";
};
/**
* Highlights the given node in the suggestions dropdown.
* @scope private
* @param oSuggestionNode The node representing a suggestion in the dropdown.
*/
AutoSuggestControl.prototype.highlightSuggestion = function (oSuggestionNode) {
for (var i = 0; i < this.layer.childNodes.length; i++) {
var oNode = this.layer.childNodes[i];
if (oNode == oSuggestionNode) {
oNode.className = "current"
} else if (oNode.className == "current") {
oNode.className = "";
}
}
};
/**
* Initializes the textbox with event handlers for
* auto suggest functionality.
* @scope private
*/
AutoSuggestControl.prototype.init = function () {
//save a reference to this object
var oThis = this;
//assign the onkeyup event handler
this.textbox.onkeyup = function (oEvent) {
//check for the proper location of the event object
if (!oEvent) {
oEvent = window.event;
}
//call the handleKeyUp() method with the event object
oThis.handleKeyUp(oEvent);
};
//assign onkeydown event handler
this.textbox.onkeydown = function (oEvent) {
//check for the proper location of the event object
if (!oEvent) {
oEvent = window.event;
}
//call the handleKeyDown() method with the event object
oThis.handleKeyDown(oEvent);
};
//assign onblur event handler (hides suggestions)
this.textbox.onblur = function () {
oThis.hideSuggestions();
};
//create the suggestions dropdown
this.createDropDown();
};
/**
* Selects a range of text in the textbox.
* @scope public
* @param iStart The start index (base 0) of the selection.
* @param iEnd The end index of the selection.
*/
AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iEnd /*:int*/) {
//use text ranges for Internet Explorer
if (this.textbox.createTextRange) {
var oRange = this.textbox.createTextRange();
oRange.moveStart("character", iStart);
oRange.moveEnd("character", iEnd - this.textbox.value.length);
oRange.select();
//use setSelectionRange() for Mozilla
} else if (this.textbox.setSelectionRange) {
this.textbox.setSelectionRange(iStart, iEnd);
}
//set focus back to the textbox
this.textbox.focus();
};
/**
* Builds the suggestion layer contents, moves it into position,
* and displays the layer.
* @scope private
* @param aSuggestions An array of suggestions for the control.()//////////////////////////////////////////////////////////////这里要改
*/
AutoSuggestControl.prototype.showSuggestions = function (bSuggestions /*:Array*/) {
var oDiv = null;
var aSuggestions = bSuggestions.getElementsByTagName("message");
this.layer.innerHTML = ""; //clear contents of the layer
//aSuggestions.length设置显示长度
for (var i = 0; i < 5; i++) {
oDiv = document.createElement("div");
oDiv.appendChild(document.createTextNode(aSuggestions[i].getElementsByTagName("text")[0].firstChild.data));
this.layer.appendChild(oDiv);
}
this.layer.style.left = (this.getLeft() - 0) + "px";
this.layer.style.top = (this.getTop() + this.textbox.offsetHeight - 11) + "px";
this.layer.style.visibility = "visible";
this.layer.style.width = "285px";
// this.layer.style.position = "absolute";
// this.layer.style.zIndex = "1989";
// this.layer.style.backgroundColor = "white";
// this.layer.style.lineHeight = "30px";
// this.layer.style.paddingTop = "10px";
};
/**
* Inserts a suggestion into the textbox, highlighting the
* suggested part of the text.
* @scope private
* @param sSuggestion The suggestion for the textbox.
*/
AutoSuggestControl.prototype.typeAhead = function (sSuggestion /*:String*/) {
//check for support of typeahead functionality
if (this.textbox.createTextRange || this.textbox.setSelectionRange) {
var iLen = this.textbox.value.length;
this.textbox.value = sSuggestion;
this.selectRange(iLen, sSuggestion.length);
}
};
//创建链接数据库
function createXMLHttp() {
if (typeof XMLHttpRequest != "undefined") {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
var aVersions = ["MSXML2.XMLHttp.5.0",
"MSXML2.XMLHttp.4.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp", "Microsoft.XMLHttp"
];
for (var i = 0; i < aVersions.length; i++) {
try {
var oXmlHttp = new ActiveXObject(aVersions[i]);
return oXmlHttp;
}
catch (oError) {
//Do nothing
}
}
}
throw new Error("XMLHttp object could be created.");
}
/**
* Provides suggestions for state/province names.
* @class
* @scope public
*/
function SuggestionProvider() {
this.xhr = new createXMLHttp();
}
/**
* Request suggestions for the given autosuggest control.
* @scope protected
* @param oAutoSuggestControl The autosuggest control to provide suggestions for.
*/
SuggestionProvider.prototype.requestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/,
bTypeAhead /*:boolean*/) {
var oXHR = this.xhr;
//cancel any active requests
if (oXHR.readyState != 0) {
oXHR.abort();
}
//define the data
//var oData = {
// requesting: "StatesAndProvinces",
// text: oAutoSuggestControl.userText,
// limit: 9
//};
var searchV = oAutoSuggestControl.userText;
if (searchV) {
var urlss = "SearchSuggest.aspx?keyword=" + encodeURI(searchV) + "&limit=5" + "&t=" + new Date().getTime();
//open connection to server
oXHR.open("get", urlss, true);
oXHR.onreadystatechange = function () {
if (oXHR.readyState == 4) {
//evaluate the returned text JavaScript (an array)
var aSuggestions = oXHR.responseXML;
//provide suggestions to the control
oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
}
}
oXHR.send(null);
};
//send the request
};
//search.css 样式
.sstxtbox {
width: 285px;
height: 20px;
line-height: 20px;
padding: 3px 0;
border: 1px solid;
}
div.suggestions_F {
-moz-box-sizing: border-box;
box-sizing: border-box;
background-color: white;
border: 1px solid #AAAAAA;
border-top:0px;
width:285px;
overflow:hidden;
position: absolute;
z-index:1989;
line-height:30px;
}
div.suggestions_F div {
cursor: default;
padding: 0px 3px;
white-space:nowrap;
}
div.suggestions_F div.current {
background-color: #3366cc;
color: white;
}
.sstxtbox:focus { outline:none; }
.fudong {
display: block;
position: fixed;
_position: absolute;
z-index: 99999;
bottom: 0px;
right: 0px;
}