您的位置:首页 > 编程语言 > Java开发

使用Ajax模仿Google suggest的搜索提示(Java+JSP+JS实现)

2014-12-20 09:13 711 查看

最近项目需要作一个类似google suggest的搜索提示功能,在网上找了一些资料,自己弄弄就出来了。项目的关键是JS。

实际运行效果:

即使在输入的时候前面有空格,也可以正确判断。

工程结构:

Keywords.java

package com.bird.bean;

public class Keywords {
private String content;

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public Keywords(String content) {
this.content = content;
}

public Keywords() {

}
}


DBManager.java

package com.bird.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBManager {
public DBManager() {
}

public static Connection getConnection() {
// String driver = "oracle.jdbc.driver.OracleDriver";
String driver = "com.mysql.jdbc.Driver";
// String url = "jdbc:oracle:thin:@133.0.129.6:1521:oracle";
String url = "jdbc:mysql://127.0.0.1:3306/itbird";
// String username = "nrmdb";
// String passwd = "nrmoptr";
String username = "root";
String passwd = "root";
Connection connection = null;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, username, passwd);
} catch (Exception ex) {
ex.printStackTrace();
}
return connection;
}

public static void closeAll(Connection con, PreparedStatement pstmt,
ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
GetKeywordsResults.java

package com.bird.DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import com.bird.bean.Keywords;
import com.bird.common.DBManager;

public class GetKeywordsResults {
@SuppressWarnings("null")
public ArrayList<Keywords> getKeywordsResults(String keyword) {
ArrayList<Keywords> list = new ArrayList<Keywords>();
Keywords key = null;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

String sql = "select content from keywords where content like '%"
+ keyword + "%'";

try {
conn = DBManager.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();

while (rs.next()) {

key = new Keywords();

System.out.println("类似关键词:" + rs.getString(1));

key.setContent(rs.getString(1));

list.add(key);
}

} catch (Exception e) {
e.printStackTrace();
} finally {
DBManager.closeAll(conn, pstmt, rs);
}

return list;
}
}
GetKeywordServlet.java

package com.bird.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bird.DAO.GetKeywordsResults;
import com.bird.bean.Keywords;

public class GetKeywordServlet extends HttpServlet {

/**
* 2014-12-18
*
* @author GHYZ
*/
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("123");
resp.setContentType("text/xml;charset=UTF-8");
resp.setHeader("Cache-Control", "no-cache");

// save keyword
String param = null;

String rawQueryStr = req.getQueryString();
String queryStr = java.net.URLDecoder.decode(rawQueryStr, "utf-8");
String[] result = queryStr.split("=");

// keyword
try {
param = result[1];
String pattern = "([\'\"-+*/^()\\]\\[])";
param = param.replaceAll(pattern, "");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("error input!");
return ;
}
param = param.trim();

System.out.println("--->" + param);
ArrayList<Keywords> list = null;

try {
System.out.println("in list Size");
list = new ArrayList<Keywords>();
list = (new GetKeywordsResults().getKeywordsResults(param));
System.out.println(list.size() + "listSize");

} catch (Exception e) {
System.out.println("input error!");
}

String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml += "<message>";
Iterator<Keywords> iter = list.iterator();
String content;
while (iter.hasNext()) {
Keywords key = iter.next();
content = key.getContent();
xml += "<info>" + content + "</info>";
}
xml += "</message>";
resp.getWriter().write(xml);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);

}

}


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
<servlet>
<servlet-name>getKeywordServlet</servlet-name>
<servlet-class>com.bird.servlet.GetKeywordServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getKeywordServlet</servlet-name>
<url-pattern>/getKeywordServlet</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>


build.js

/*
* 判断按键的JavaScript代码
*/

var arrOptions = new Array(); //定义一个保存服务器返回的数组
var strLastValue = ""; //定义保存每次向服务器发送请求的参数
var theTextBox; //定义表示文本输入变量
var currentValueSelect = -1; //定义下拉提示框中默认的选项

window.onload = function() {
var elemSpan = document.createElement("span");
elemSpan.id = "spanOutput";
elemSpan.className = "spanTextDropdown";
document.body.appendChild(elemSpan);
document.Form1.txtUserInput.onkeyup = GiveOptions;
};

function GiveOptions() { //按下键的调用方法
var intKey = -1;

if (window.event) {
intKey = event.keyCode;
theTextBox = event.srcElement;
}

if (theTextBox.value.length == 0) { //文本框内容为空
HideTheBox();
strLastValue = "";
return false;
}

if (intKey == 13) {
//按下Enter键
GrabHighlighted();
theTextBox.blur();
return false;
} else if (intKey == 38) {
//按下 up 键
MoveHightlighted(-1);
return false;
} else if (intKey == 40) {
//按下 down 键
MoveHightlighted(1);
return false;
}

//进行内容比较
if (theTextBox.value.indexOf(strLastValue) != 0 || arrOptions.length == 0
|| (strLastValue.length == 0 && theTextBox.value.length > 0)
|| (theTextBox.value.length <= strLastValue.length) ) {
strLastValue = theTextBox.value;
strLastValue = strLastValue.replace(/^\s*\'|\s*$/g,"");
TypeAhead(theTextBox.value);
} else {
BuildList(theTextBox.value);
}

};

function removeAllSpace(str) {
return str.replace(/\s+/g, "");
};

function TypeAhead(xStrText) { //发送请求方法
xStrText = removeAllSpace(xStrText);
if (xStrText == "") return; //判断如果输入框内容为空
var url = "getKeywordServlet?param=" + xStrText; //创建发送地址变量
if ( window.XMLHttpRequest ) { //判断浏览器
req = new XMLHttpRequest();
} else if (window.ActiveXObject()) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
if (req) {
req.open("GET" , url, true);  //打开连接
//设置回调函数
req.onreadystatechange  = function() {
if (req.readyState==4 && req.status==200) {
parseMessage();
}
};
req.send(null); //实现发送
}
};

function parseMessage() { //分析服务器返回数据
var xmlDoc = req.responseXML.documentElement; //获取返回的XML文件对象
var nodeInfo = xmlDoc.getElementsByTagName("info");  //获取标记<info>
arrOptions = new Array(); //创建一个数组对象
for (var i = 0; i < nodeInfo.length; i ++) {
arrOptions[i] = nodeInfo[i].firstChild.nodeValue; //存储<info>到数组对象中
}
BuildList(theTextBox.value);
strLastValue = theTextBox.value;
};

function BuildList(theText) { //创建下拉提示框方法
//alert("buidList");
theText = removeAllSpace(theText);
SetElementPosition();
var inner = "";
var theMatches = MakeMatches(theText); //获取索要匹配的对象
for (var i = 0; i < theMatches.length; i++) {
inner += theMatches[i];
}
if (theMatches.length > 0) {
document.getElementById("spanOutput").innerHTML = inner;
document.getElementById("OptionsList_0").className = "spanHighElement";
currentValueSelect = 0;
} else {
HideTheBox();
}
};

function SetElementPosition() {
var selectedPosX = 0;
var selectedPosY = 0;
//创建关于提示框的长度和宽度的变量
var theElement = document.Form1.txtUserInput;
//var theTextBoxInt = document.Form1.txtUserInput;
if (!theElement) {
alert("not found");
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;
xPosElement.style.width = theElemWidth;
xPosElement.style.top = selectedPosY + theElemHeight;
xPosElement.style.display = "block";
};

var countForId = 0;
function MakeMatches(xCompareStr) {
countForId = 0;
var matchArray = new Array();
for ( var i = 0; i < arrOptions.length; i++) {
//遍历arrOptions对象
var regExp = new RegExp(xComp
9996
areStr , "ig");

if ((arrOptions[i].search(regExp)) >= 0 ) {
//当有匹配的项,调用CreatUnderline()方法返回字符串
matchArray[matchArray.length] = CreateUnderline(arrOptions[i],
xCompareStr, i);
} else {
continue;
}
}
return matchArray;
};

function MoveHightlighted(xDir) {
if (currentValueSelect >= 0) {
//获取按键的值
newValue = parseInt(currentValueSelect) + parseInt(xDir);
if (newValue > -1 && newValue < countForId) {
currentValueSelect = newValue;
SetHighColor(null);
}
}
};

function ReDraw() {
BuildList(document.Form1.txtUserInput.value);
};

function GrabHighlighted() {
if (currentValueSelect >= 0) {
xVal = document.getElementById("OptionsList_" + currentValueSelect).getAttribute("theArrayNumber");
SetText(xVal);
HideTheBox();
}
};

function HideTheBox() {
document.getElementById("spanOutput").style.display = "none";
currentValueSelect = -1;
};

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 + "'>";
countForId++;
var regExp = new RegExp(xTextMatch , "ig");
var start = xStr.search(regExp);
var matchedText = xStr.substring(start, start + xTextMatch.length);
var Replacestr = xStr.replace(regExp, undeStart + matchedText + undeEnd);
return selectSpanStart + selectSpanMid + Replacestr + selectSpanEnd;
};
function SetHighColor(theTextBox) {
if (theTextBox) {
currentValueSelect = 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_' + currentValueSelect).className = 'spanHighElement';
};
function SetText(xVal) {
theTextBox = document.Form1.txtUserInput;
theTextBox.value = arrOptions[xVal];
document.getElementById("spanOutput").style.display = "none";
currentValueSelect = -1;
};
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>Google Suggest</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" src="build.js"></script>
<style type="text/css">
.spanTextDropdown {
left: 88px;
width: 171px;
top: 29px;
display: none;
margin-left: 80px;
border: 1px solid gray;
margin-top: -18px;

}
.spanHighElement {
background:navajowhite;
}
</style>
</head>

<body onResize="ReDraw()">
<div>
<form name="Form1" autocomplete="off" id="Form1">
Text Box:
<input type="text" name="txtUserInput" style="width: 182px;"/>
<!-- hidden zone -->
<input type="hidden" name="txtUserValue" id="hidden1"/>
<!-- help text input  -->
<input type="text" name="txtIgnore" style="display: none;"/>
</form>
</div>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐