solr进阶七:与jQuery结合的自动补全功能
网上有大量的jQuery自动补全功能的插件,我实现这个功能是采用网友写好的纯jQuery代码,而不是采用插件,因为特效会差很多。而后台的数据是从solr那边获取过来,通过整理,放到对象中,再放到集合中,然后在servlet层解开,生成xml文件,返回到前台,形成自动提示补全的功能,流程非常简单,没有采用框架技术,只是用了JSP的servlet来做中间层而已。
目录结构如下:
1.先编写实体类src\com\lifeix\entity\Word.java
- package com.lifeix.entity;
- /**
- * Created by lhx on 14-12-9 上午9:38
- *
- * @project jspProject
- * @package com.lifeix.entity
- * @blog http://blog.****.net/u011439289
- * @email [email protected]
- * @Description
- */
- public class Word {
- //次数
- private int number ;
- //名称
- private String name ;
- public Word(){}
- public Word(int number, String name){
- this.number = number ;
- this.name = name ;
- }
- public int getNumber() {
- return number;
- }
- public void setNumber(int number) {
- this.number = number;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
2.编写一个servlet测试一下src\com\lifeix\servlet\AutoCompleteServlet.java
- package com.lifeix.servlet;
- import com.lifeix.entity.Word;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- /**
- * Created by lhx on 14-12-9 上午9:31
- *
- * @project jspProject
- * @package ${PACKAGE_NAME}
- * @blog http://blog.****.net/u011439289
- * @email [email protected]
- * @Description
- */
- public class AutoCompleteServlet extends HttpServlet {
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- StringBuffer sf = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- sf.append("<message>");
- List<Word> list = new ArrayList<Word>(10);
- Word word = null ;
- for (int i = 0; i < 10; i++) {
- word = new Word(i, "abd" + i);
- list.add(word);
- }
- Iterator<Word> it = list.iterator();
- while (it.hasNext()){
- Word word1 = it.next();
- if (word1 == null){
- continue;
- }
- int number = word1.getNumber();
- String name = word1.getName();
- sf.append("<word>"+name);
- sf.append("</word>");
- }
- sf.append("</message>");
- PrintWriter pw = null;
- try {
- response.setContentType("text/xml;charset=utf-8");
- response.setCharacterEncoding("UTF-8");
- response.setHeader("Cache-Control", "no-cache");
- pw = response.getWriter();
- pw.print(sf.toString());
- pw.flush();
- }catch (Exception e) {
- e.printStackTrace();
- }
- finally {
- if (pw != null)
- pw.close();
- }
- }
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doPost(request,response);
- }
- }
启动tomcat,访问这个servlet,结果如下:
证明返回的确实是XML文档。
3.直接编写页面文档jspProject\web\auto2.html
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>jQuery 自动完成功能(优化版)</title>
- <script type="text/javascript" src="js/jquery-2.1.1.js"></script>
- </head>
- <body>
- <script type="text/javascript">
- var highlightindex = -1;//表示当前高亮节点
- var timeoutId;
- $(document).ready(function() {
- var wordInput = $("#word");//文本框
- var wordInputOffset = wordInput.offset();//获得文本框位置
- $("#auto").hide().css("border", "1px black solid").css("position", "absolute")
- .css("top", wordInputOffset.top + wordInput.height() + 5 + "px")
- .css("left", wordInputOffset.left + "px").width(wordInput.width() + 3 + "px");
- wordInput.keyup(function(event) {
- //处理文本框中的键盘事件
- //如果输入字母,将文本框中最新信息发送给服务器
- var myEvent = event || window.event;
- var keyCode = myEvent.keyCode;//获得键值
- if (keyCode == 27) {
- var wordText = $("#word").val();
- autoHide();
- wordInput.text(wordText);
- }
- else {
- if (keyCode >= 65 && keyCode <= 90 || keyCode == 8 || keyCode == 46) { //8对应退格键,46对应删除键
- var wordText = $("#word").val();//获得文本框中的内容
- var autoNode = $("#auto");
- if (wordText != "") {
- clearTimeout(timeoutId);//对上次未完成的延时操作进行取消
- //延时操作,减少与服务器的交互次数,延时500ms,防止用户操作过快
- timeoutId = setTimeout(function() {
- $.post("AutoCompleteServlet", {word:wordText}, function(data) {//发送数据,第二项是属性名对应属性值
- var jqueryObj = $(data);//将dom对象data转换成jQuery的对象
- var wordNodes = jqueryObj.find("word");//找到所有word节点
- autoNode.html("");
- wordNodes.each(function(i) { //i是索引,用来给id赋值
- var wordNode = $(this);//获取单词内容
- var newDivNode = $("<div>").attr("id", i).css("backgroundColor", "white");
- newDivNode.html(wordNode.text()).appendTo(autoNode);//新建div节点,加入单词内容
- //增加鼠标进入事件,高亮节点
- newDivNode.mouseover(function() {
- //将原来高亮的节点取消高亮
- if (highlightindex != -1) {
- $("#auto").children("div").eq(highlightindex)
- .css("backgroundColor", "white");
- }
- //记录新的高亮索引
- highlightindex = $(this).attr("id");
- $(this).css("backgroundColor", "#3366CC").css("cursor","pointer");
- });
- //增加鼠标移出事件,取消节点高亮
- newDivNode.mouseout(function() {
- if (keyCode == 13) { //判断是否按下回车键
- //下拉框有高亮
- if (highlightindex != -1) {
- lightEventHide();
- highlightindex = -1;
- } else {
- alert("文本框中的[" + $("#word").val() + "]被提交了");
- autoHide();
- $("#word").get(0).blur();//让文本框失去焦点
- }
- //取消鼠标移出节点的高亮
- //$(this).css("backgroundColor", "white");
- }
- }
- );
- //增加鼠标点击事件,可以进行补全
- newDivNode.click(function() {
- //取出高亮节点的文本内容
- var comText = $(this).text();
- autoHide();
- highlightindex = -1;
- //文本框内容变为高亮节点内容
- $("#word").val(comText);
- });
- });
- //添加单词内容到弹出框
- if (wordNodes.length > 0) {
- autoNode.show();
- } else {
- autoNode.hide();
- highlightindex = -1;//弹出框隐藏,高亮节点索引设成-1
- }
- }, "xml");
- }, 300);
- }
- else
- {
- autoNode.hide();
- highlightindex = -1;
- }
- } else if (keyCode == 38 || keyCode == 40) { //判断是否输入的是向上38向下40按键
- if (keyCode == 38) {
- var autoNodes = $("#auto").children("div").css("background-color", "white");
- if (highlightindex != -1) {
- autoNodes.eq(highlightindex).css("background-color", "white");
- highlightindex--;
- } else {
- lightEvent();
- highlightindex = autoNodes.length - 1;
- }
- if (highlightindex == -1) {
- highlightindex = autoNodes.length - 1;//如果改变索引值后index变成-1,则将索引值指向最后一个元素
- }
- lightEvent();
- autoNodes.eq(highlightindex).css("backgroundColor", "#3366CC");
- }
- if (keyCode == 40) {
- var autoNodes = $("#auto").children("div");
- if (highlightindex != -1) {
- autoNodes.eq(highlightindex).css("background-color", "white");
- }
- highlightindex++;
- if (highlightindex == autoNodes.length) {
- highlightindex = 0;//如果改变索引值等于最大长度,则将索引值指向第一个元素
- }
- lightEvent();
- autoNodes.eq(highlightindex).css("backgroundColor", "#3366CC");
- }
- } else if (keyCode == 13) { //判断是否按下回车键
- //下拉框有高亮
- if (highlightindex != -1) {
- lightEventHide();
- highlightindex = -1;
- } else {
- alert("文本框中的[" + $("#word").val() + "]被提交了");
- $("#auto").hide();
- $("#word").get(0).blur();//让文本框失去焦点
- }
- //下拉框没有高亮
- }
- }
- }
- )
- ;
- $("input[type='button']").click(function() {
- alert("文本框中的[" + $("#word").val() + "]被提交了");
- });
- });
- function lightEventHide(){
- var comText = $("#auto").hide().children("div").eq(highlightindex).text();
- $("#word").val(comText);
- }
- function lightEvent(){
- var comText = $("#auto").children("div").eq(highlightindex).text();
- $("#word").val(comText);
- }
- function autoHide(){
- $("#auto").hide();
- }
- </script>
- <h3>
- <center>仿google自动补全(jQuery优化版)</center>
- </h3>
- <br />
- <table align="center">
- <tr><td>
- <input type="text" id="word" maxlength=2048 size=55 />
- <br/>
- <td></tr>
- <tr><td align="center">
- <input type="button" value="shiyang 搜索"/>
- </td></tr>
- </table>
- <br />
- <div id="auto"></div>
- </body>
- </html>
这个例子引用:施杨de编程世界www.cnblogs.com/shiyangxt
4.重启tomcat,打开这个页面,访问:
不管是首字母还是中间的,都会有提示了!
这个demo没有和solr结合,现在我们加入solr,直接从solr里面取数据!
访问solr管理页面,选择要搜索的core和字段,还有值,看看有没有搜索结果出来。后期会加入可以动态编辑的字段还有值,使例子更实用些。
1.编写后台类,与solr交互,获取数据src\com\lifeix\util\SolrGetFtTopic.java
- package com.lifeix.util;
- import com.lifeix.entity.Word;
- import org.apache.solr.client.solrj.SolrServer;
- import org.apache.solr.client.solrj.SolrServerException;
- import org.apache.solr.client.solrj.impl.HttpSolrServer;
- import org.apache.solr.client.solrj.response.QueryResponse;
- import org.apache.solr.common.SolrDocument;
- import org.apache.solr.common.SolrDocumentList;
- import org.apache.solr.common.params.ModifiableSolrParams;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * Created by lhx on 14-12-9 上午10:30
- *
- * @project jspProject
- * @package com.lifeix.util
- * @blog http://blog.****.net/u011439289
- * @email [email protected]
- * @Description
- */
- public class SolrGetFtTopic {
- private static final String SOLR_URL = "http://192.168.199.22:8080/xxx/";
- public List<Word> queryAll(){
- ModifiableSolrParams params = new ModifiableSolrParams();
- params.set("q","topicName:次");
- params.set("start",0);
- params.set("rows",Integer.MAX_VALUE);
- params.set("sort","score desc");
- params.set("f1","*,score");
- SolrServer server = new HttpSolrServer(SOLR_URL);
- List<Word> listWord = new ArrayList<Word>() ;
- Word word = null ;
- try {
- QueryResponse response = server.query(params);
- SolrDocumentList list = response.getResults();
- for (int i = 0; i < list.size(); i++) {
- word = new Word();
- SolrDocument document = list.get(i);
- word.setName( (String)document.getFieldValue("topicName") );
- listWord.add(word);
- }
- return listWord ;
- } catch (SolrServerException e) {
- e.printStackTrace();
- }
- return null ;
- }
- }
2.修改src\com\lifeix\servlet\AutoCompleteServlet.java,主要就是把静态数据换成了从solr后台获取的list集合数据
- package com.lifeix.servlet;
- import com.lifeix.entity.Word;
- import com.lifeix.util.SolrGetFtTopic;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.Iterator;
- import java.util.List;
- /**
- * Created by lhx on 14-12-9 上午9:31
- *
- * @project jspProject
- * @package ${PACKAGE_NAME}
- * @blog http://blog.****.net/u011439289
- * @email [email protected]
- * @Description
- */
- public class AutoCompleteServlet extends HttpServlet {
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- StringBuffer sf = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- sf.append("<message>");
- SolrGetFtTopic solrGetFtTopic = new SolrGetFtTopic();
- List<Word> list = solrGetFtTopic.queryAll();
- Iterator<Word> it = list.iterator();
- while (it.hasNext()){
- Word word1 = it.next();
- if (word1 == null){
- continue;
- }
- String name = word1.getName();
- sf.append("<word>"+name);
- sf.append("</word>");
- }
- sf.append("</message>");
- PrintWriter pw = null;
- try {
- response.setContentType("text/xml;charset=utf-8");
- response.setCharacterEncoding("UTF-8");
- response.setHeader("Cache-Control", "no-cache");
- pw = response.getWriter();
- pw.print(sf.toString());
- pw.flush();
- }catch (Exception e) {
- e.printStackTrace();
- }
- finally {
- if (pw != null)
- pw.close();
- }
- }
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doPost(request,response);
- }
- }
3.前台页面的jQuery代码可以纹丝不动,重启tomcat,先访问servlet,看看数据能不能正常获取:
没问题!!访问页面,也一样没问题!