1. 程式人生 > >可模糊查詢輸入框(仿百度搜索欄)

可模糊查詢輸入框(仿百度搜索欄)

很早之前做了個通用版的,當時做的時候有個初步的想法。

1.鍵盤每輸入一個字母觸發一次(onkeyup觸發事件)
2.設定一個隱藏框<div></div>(div的css樣式display設為none 設定寬高 定好位置 
3.每次觸發(onkeyup)更改div的display為block  

js: document.getElementById(“div的id”).style.display="block"  

jq: $("#id").css("dispaly","block");
同時獲取文字框值document.getElementById(“input的id”).value賦給一個變數  
4.用ajax後臺連線資料庫顯示出(echo)和你輸入的字元匹配的資料放到一個表格裡  

就是目標<div><table></table></div> table設樣式 ;當然也可以用<div><ul><li></li></ul></div> 都行

5.把返回的http.responseText寫入到div框中document.getElementById(“div的id”).innerHTML=http.responseText

我用的js寫法的初級ajax

6、只做了滑鼠事件,鍵盤事件沒做(想要的自己搞)

先看下效果:

             

          


這個時候要注意樣式中有個屬性overflow-x:hidden; 可以消除x軸的狀態列。為什麼說這個呢,因為我是自學前端的,所以有些css屬性不是很瞭解 被這個坑過就蠻提一下。還有一個就是彈層要注意 z-index:1000;這個設定高一點,要不然會被其他控制元件遮擋掉。

廢話不說了,上原始碼

樣式:

#div_EmpNo
        {
            position: absolute;
            border: 1px solid #abcee4;
            width: 175px;
            height: 200px;
            overflow: auto;
	    overflow-x:hidden;
            display: none;
            background: #f7f7f7;
	    line-height: 1.5em;
            font-size: 11px;
            clear: both;
            z-index: 9999;
        }
/*模糊查詢彈層table中title 行 一列 兩列等*/
        .dialogTitle
        {
            background-color: #E6E6FA;
            float: left;
            display: block;
            height: 20px;
            width: 50%;
            cursor: default;
            font-size: 110%;
        }
        .dialogTitle1
        {
            background-color: #E6E6FA;
            height: 20px;
            width: 100%;
            float: left;
            display: block;
            cursor: default;
            font-size: 110%;
        }
/*模糊查詢彈層table簡單樣式*/
.gridtable
        {
            font-family: verdana,arial,sans-serif;
            font-size: 11px;
            border-collapse: collapse;
            width: 200px;
            cursor: pointer;
	    cellspacing:0;
        }
/*未查詢到資料提示*/
.dialogHint
        {
            background-color: #E6E6FA;
            height: 20px;
            width: 200px;
            float: left;
            display: block;
        }
Html:前端的改成 input輸入控制元件就行,這邊伺服器控制元件只是方便後端存取資料。autocomplete="off" 禁止歷史輸入

重點 onkeyup事件就可以了

<div id="div_EmpNo"></div>
    <div class="contentContainer">
        <asp:TextBox ID="TextBox_STORE_NUMBER" runat="server" MaxLength="40" CssClass="pub_clsInputEdit TextBoxElement STORE_NUMBER elementDisplayYes"
            onkeyup="GetStoreInfo()" autocomplete="off"></asp:TextBox></div>

js+jq程式碼(有時候寫純js太累,就偶爾混著用),下面第一個是比較早之前寫的 有些不完善地方,後面補了些坑。
function GetStoreInfo()
        {
            var showDiv=document.getElementById ("div_EmpNo");
            var etest = document.getElementById("<%=TextBox_STORE_ACCOUNT.ClientID%>").value.trim();
            if (etest == '' || etest == 'null' || etest == undefined) {
                document.getElementById("div_EmpNo").style.display = "none";
            } else {
                document.getElementById("div_EmpNo").style.display = "block";
            }    
             //控制彈層和輸入框相對位置
            var height = $('#<%=TextBox_STORE_ACCOUNT.ClientID%>').height();
            var X1 = $('#<%=TextBox_STORE_ACCOUNT.ClientID%>').offset().left;
            var Y1 = $('#<%=TextBox_STORE_ACCOUNT.ClientID%>').offset().top;
            showDiv.style.position = "absolute";
            showDiv.style.left = X1 + "px";
            showDiv.style.top = Y1 + height + 8 + "px";
            ClearStoreData();
            var XMLHttp=false;
            showDiv.innerHTML="";
            if(window.ActiveXObject)
            {
                XMLHttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if(window.XMLHttpRequest)
            {
               XMLHttp=new XMLHttpRequest(); 
            }
            
            if(!XMLHttp && typeof XMLHttpRequest!='undefined!')
            {
                XMLHttp=new XMLHttpRequest();
            }
            
            XMLHttp.onreadystatechange=function()  
            {  
                if(XMLHttp.readyState==4)  
                {  
                    if(XMLHttp.status==200)
                    {  
                        showDiv.innerHTML= XMLHttp.responseText;  
                    }
                }
            }
            var sql=document.getElementById("<%=HiddenStoreSql.ClientID%>").value;
            var funType="GetStoreNoInfo";
            var url = "ServerData.ashx?Applyer=" + escape(etest) + "&strsql=" + escape(sql) + "&fun=" + escape(funType) + "&id=" + new Date().getTime(); 
            XMLHttp.open("get",url,true);  
            XMLHttp.setRequestHeader("Content-Type","text/xml");  
            XMLHttp.send(null);
        }
補了些坑之後的程式碼:
function GetStoreInfo()
        {
            var showDiv=document.getElementById ("div_EmpNo");
            var etest = document.getElementById("<%=TextBox_STORE_NUMBER.ClientID%>").value.trim();
            if (etest == '' || etest == 'null' || etest == undefined) {
                showDiv.style.display = "none";
                return false;
            } else {
                showDiv.style.display = "block";
            }    
            //控制彈層和輸入框相對位置
            var height = $('#<%=TextBox_STORE_NUMBER.ClientID%>').height();
            var X1 = $('#<%=TextBox_STORE_NUMBER.ClientID%>').offset().left;
            var Y1 = $('#<%=TextBox_STORE_NUMBER.ClientID%>').offset().top;
            showDiv.style.position = "absolute";
            showDiv.style.left = X1 + "px";
            showDiv.style.top = Y1 + height + 8 + "px";
            showDiv.innerHTML="";//清空原先資料,動態獲取最新資料
            $("input[id*=TextBox_STORE_NAME]").val('');
            var XMLHttp=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
            XMLHttp.onreadystatechange=function(){  
                 if(XMLHttp.readyState==4 && XMLHttp.status==200){   
                     showDiv.innerHTML= XMLHttp.responseText;  
                 }
            } 
            var sql=document.getElementById("<%=HiddenStoreSql.ClientID%>").value;
            var funType="GetStoreNoInfo";
            var url = "ServerData.ashx?Applyer=" + escape(etest) + "&strsql=" + escape(sql) + "&fun=" + escape(funType) + "&id=" + new Date().getTime(); 
            XMLHttp.open("get",url,true);  
            XMLHttp.setRequestHeader("Content-Type","text/xml");  
            XMLHttp.send(null);
        }

有些東西要為初學者解釋一下,我就被自己坑很多次
if (etest == '' || etest == 'null' || etest == undefined) {
                document.getElementById("div_EmpNo").style.display = "none";
                return false;
            } else {
                document.getElementById("div_EmpNo").style.display = "block";
            } 
加了return false;減小資源浪費 空格的時候就不查詢,免得輸入框連續空格。。。,
var etest = document.getElementById("<%=TextBox_STORE_NUMBER.ClientID%>").value.trim();

獲取關鍵字資訊 空格還是清除一下的;

var height = $('#<%=TextBox_STORE_NUMBER.ClientID%>').height();
            var X1 = $('#<%=TextBox_STORE_NUMBER.ClientID%>').offset().left;
            var Y1 = $('#<%=TextBox_STORE_NUMBER.ClientID%>').offset().top;
這段是為了獲取 輸入框的高度 還有它位置 就是css top  left的值,說到這個值就有必要再嘮叨一下。上面是jq寫法

js寫法

document.getElementById("<%=TextBox_STORE_NUMBER.ClientID%>").offsetLeft; 就是css left的值
<pre name="code" class="javascript">document.getElementById("<%=TextBox_STORE_NUMBER.ClientID%>").style.left;基本上這兩個取到的值是一樣
但是有一點要注意style.left是讀寫  offsetLeft只能讀; style.left的到結果是字串 比如20px,而offsetLeft得到的數值是20 可以直接計算的;style.left要獲取值 只能在html中定義,才有值如上面的程式碼。因為css那邊先定義 left:xx px;未在html頁面上給style.left=xx+'px';操作,則獲取到的值為空;
showDiv.style.position = "absolute";
            showDiv.style.left = X1 + "px";
            showDiv.style.top = Y1 + height + 8 + "px";
            showDiv.innerHTML="";
            $("input[id*=TextBox_STORE_NAME]").val('');
給層絕對定位在 模糊查詢框左下方,最後一行程式碼是模糊查詢帶出值清空其他欄位的。
var XMLHttp=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
            XMLHttp.onreadystatechange=function(){  
                 if(XMLHttp.readyState==4 && XMLHttp.status==200){   
                     showDiv.innerHTML= XMLHttp.responseText;  
                 }
            } 
根據ajax操作不同階段 可以再不同狀態碼下做相應操作,比如404找不到頁面等
var sql=document.getElementById("<%=HiddenStoreSql.ClientID%>").value;
            var funType="GetStoreNoInfo";
            var url = "ServerData.ashx?Applyer=" + escape(etest) + "&strsql=" + escape(sql) + "&fun=" + escape(funType) + "&id=" + new Date().getTime(); 
            XMLHttp.open("get",url,true);  
            XMLHttp.setRequestHeader("Content-Type","text/xml");  
            XMLHttp.send(null);
sql是查詢語句 我通過後臺訪問資料庫包獲取的 這個不管 只要知道是查詢語句 有個where等你的關鍵字就行

ajax get的方法會快取 所以加個時間new Date.getTime()去除快取。ajax get post的區別,下次有空再說了

後端接收傳值 查詢 返回結果 以下示例是 .net 一般處理程式.ashx與前臺的互動

string etest = context.Request.QueryString["Applyer"];
            string p_sql = context.Request.QueryString["strsql"];

            int num = Convert.ToInt32(context.Request.QueryString["formNo"]);
            string FunType = context.Request.QueryString["fun"];

if (FunType == "GetStoreNoInfo")
            {
                sqlStr = string.Format(p_sql, etest);
                DataSet ds = new Facade.SFFORM077().ExecuteQuery(sqlStr);
                StringBuilder strBuild = new StringBuilder();
                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    strBuild.Append("<table id=\"tableShow\" class=\"gridtable\" ");
                    strBuild.AppendFormat("<tr><div class=\"dialogTitle\">" + title1 + "</div><div class=\"dialogTitle\">" + title2 + "</div></tr>");
                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        strBuild.Append("<tr  id='" + dr["VALUE"] + "' onmouseover=\"this.bgColor='#FAEBD7'\" onmouseout=\"this.bgColor=''\"  onclick=\" ClickStoreNo(this)\" >");
                        strBuild.AppendFormat("<td >{0}</td> ", dr["VALUE"].ToString());
                        strBuild.AppendFormat("<td >{0}</td> ", dr["DISPLAY"].ToString());
                        strBuild.Append("</tr>");
                    }
                    strBuild.Append("</table>");
                }
                else
                {
                    strBuild.Append("<div class=\"dialogHint\">未匹配到相關資料!</div>");
                }
                context.Response.Write(strBuild.ToString());
                context.Response.End();
            }

前臺的這句就是接收 返回的資料
if(XMLHttp.readyState==4 && XMLHttp.status==200){   
                     showDiv.innerHTML= XMLHttp.responseText;  
                 }
當然mouseover out等事件可以不寫在裡面 另外獨立寫也行 就不多說了。顯示兩列資料什麼的自己改改就行了,拼接多寫一兩句就行了(當然拼接的也可以通過xml檔案來傳)
<pre name="code" class="csharp">onclick=\" ClickStoreNo(this)\" 
後端新增的這個事件 是獲取目標行點選事件,
<pre name="code" class="javascript">function ClickStoreNo(obj)
        {
            var id=$(obj).attr("id");
            var storeAccount=$(obj).children("td").eq(0).text();
            document.getElementById("<%=TextBox_STORE_NUMBER.ClientID %>").value = storeAccount; 
            document.getElementById("div_EmpNo").style.display = "none";
        }

大概就是這樣了。。。 路過的大神不要鄙視我。。。