Ajax异步自动填充
一、案例介绍在开发中,通常情况下,搜索功能是非常常见的,类似京东,当我们输入搜索条件时,将自动填充我们需要的数据,并提供选择,我们将此类功能称为:自动填充(autocomplete)。如图1所示: 图1:自动填充案例演示 注解: 当在收索框中输入“yifu”,下来框中就会出现对应相关的信息。 二、案例相关技术2.1、JSON数据1、什么是JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON采用完全独立于语言的文本格式,就是说不同的编程语言JSON数据是一致的,如图2所示。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。 图2:JSON数据传输图解 2、JSON格式: JSON对象格式 {"key":"value","key":"value",....} 键和值使用冒号分隔。 标准规范要求key必须使用双引号,value如果没有使用双引号表示变量。 JSON数组 [ obj , obj , obj , ....] 表示一组值,多个值使用逗号分隔 例如: 1 <script type="text/javascript"> 2 //1 json对象 3 var user = { 4 "username":"jack", 5 "password":"1234" 6 }; 7 alert(user.username); //通过key获得json数据 8 //2 json数组 9 var arr = ['jack','rose','tom']; 10 alert(arr[1]); 11 //3 综合案例 12 var data = [ 13 {"id":"b001","title":"javaweb","price":"998"}, 14 {"id":"b002","title":"java 基础","price":"123"}, 15 {"id":"b003","title":"ssh","price":"250"}, 16 ]; 17 alert(data[1].title); 18 </script> 2.2、JSON-LIB工具l json-lib是将java对象与json数据相互转换的工具。 l 第三方工具,使用时需要导入jar包(json-lib-2.4-jdk15.jar)。 l 常用对象: JSONObject, java对象(JavaBean、Map)与JSON数据 转换工具类 JSONArray,java集合(List、Array) 与JSON数据 转换工具类 l 常用方法: static fromObject(…) ,静态方法,用于将java对象或集合转换常 jsonlib对象。 toString() 将jsonlib对象 转换成 json 字符串。 例如: 1 // map或javabean 2 Map<String, String> map = new HashMap<String, String>(); 3 map.put("username", "jack"); 4 map.put("password", "1234"); 5 String str = JSONObject.fromObject(map).toString(); 6 System.out.println(str); 7 /* 输出结果: 8 { 9 "username":"jack", 10 "password":"1234" 11 } 12 */ 13 // list 或 array 14 List<Map<String,String>> list = new ArrayList<>(); 15 list.add(map); 16 list.add(map); 17 String str2 = JSONArray.fromObject(list).toString(); 18 System.out.println(str2); 19 /* 输出结果: 20 [ 21 {"username":"jack","password":"1234"}, 22 {"username":"jack","password":"1234"} 24 */ 三、案例分析如下图3所示,当我们输入搜索条件时,将自动填充我们需要的数据的流程分析。 图3:案例分析 注解: 1.用户输入搜索条件,键盘弹起时,发送ajax请求,将用户输入的内容发送给服务器 2.1 服务器获得用户输入的内容 2.2 根据要求拼凑查询条件,商品名称需要匹配,拼音也需要匹配,用户项可以不连续。 2.3 根据拼凑条件查询商品信息 3将查询的商品信息使用json-lib转换成json数据。 4.在$.post() 回调函数中处理查询结果。 四、案例实现4.1、创建表 1 create table product( 2 pid varchar(32) primary key, 3 pname varchar(100), 4 pinyin varchar(200) 5 ); 6 7 insert into product(pid,pname,pinyin) values('p001','服装','fuzhuang'); 8 insert into product(pid,pname,pinyin) values('p002','男装','nanzhuang'); 9 insert into product(pid,pname,pinyin) values('p003','女装','nvzhuang'); 10 insert into product(pid,pname,pinyin) values('p004','电脑','diannao'); 11 insert into product(pid,pname,pinyin) values('p005','奢侈品','shechipin'); 12 insert into product(pid,pname,pinyin) values('p006','图书','tushu'); 13 insert into product(pid,pname,pinyin) values('p007','食品','shipin'); 4.2、创建Javabean 1 public class Product { 2 private String pid; 3 private String pname; 4 private String pinyin; 5 } 注解: 创建javabean时,需要自动添加get、set方法,这里就不再演示。 4.3、服务器程序l 步骤1:编写servlet,获得关键字,然后查询,将查询结果转换成json数据。 1 public class ProductFindByWordServlet extends HttpServlet { 2 public void doGet(HttpServletRequest request, HttpServletResponse response) 3 throws ServletException, IOException { 4 try{ 5 //0编码 6 request.setCharacterEncoding("UTF-8"); 7 response.setContentType("application/json;charset=UTF-8"); 8 //1 关键字 9 String word = request.getParameter("word"); 10 //2 查询 11 ProductService productService = new ProductService(); 12 List<Product> allProduct = productService.findAllByWord(word); 13 //3 转换成json 14 String jsonData = JSONArray.fromObject(allProduct).toString(); 15 response.getWriter().println(jsonData); 16 }catch(Exception e){ 17 e.printStackTrace(); 18 } 19 } l 步骤2:编写service,允许用户可以输入“汉字”、“拼音”、“若干字母”等进行查询。 1 public class ProductService { 2 /** 3 * 通过关键字查询 4 * @param word 5 * @return 6 */ 7 public List<Product> findAllByWord(String word) throws SQLException { 8 ProductDao productDao = new ProductDao(); 9 return productDao.findAll(word); 10 } 11 } l 步骤3:编写dao,查询带有条件商品信息。 1 public class ProductDao { 2 /** 3 * 条件查询商品 4 * @param condition 5 * @param params 6 * @return 7 */ 8 public List<Product> findAll(String word) throws SQLException{ 9 StringBuilder builder = new StringBuilder(); 10 List<Object> paramsList = new ArrayList<Object>(); 11 if(word != null){ 12 // 拼凑关键字的属性,hao拼凑成“%h%a%o%” 13 StringBuilder wordBuilder = new StringBuilder(); 14 wordBuilder.append("%"); 15 for(int i = 0 ; i < word.length() ; i ++ ){ 16 wordBuilder.append(word.charAt(i)).append("%"); 17 } 18 //1 汉字匹配 19 builder.append(" and pname like ?"); 20 paramsList.add(wordBuilder.toString()); 21 //2 拼音匹配 22 builder.append(" or pinyin like ?"); 23 paramsList.add(wordBuilder.toString()); 24 } 25 //转换成需要的条件 26 String condition = builder.toString(); 27 Object[] params = paramsList.toArray(); 28 QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource()); 29 String sql = "select * from product where 1=1 " + condition; 30 return queryRunner.query(sql, new BeanListHandler<Product>(Product.class), params); 31 } 32 } 4.4、浏览器JSl 步骤1:添加div和css,用于显示自动填充数据的div,图4为搜索框jsp页面。 图4:搜索框jsp页面 1 //HTML页面已经提供 2 <div id="completeShow"> 3 <ul id="itemul" class="list-group"> 4 <%-- <li class="list-group-item">Cras justo odio</li>--%> 5 </ul> 6 </div> 7 //CSS样式,“./css/main.css” 文件中已提供 8 #completeShow{ 9 border: 1px solid #999; 10 min-height: 200px; 11 position: absolute; 12 width: 196px; 13 z-index: 1000; 14 background-color: #fff; 15 border-radius: 5px; 16 display: none; 17 } l 步骤2:将查询结果显示到指定的区域,数据使用<li>包裹,使用bootstrap的list-group-item渲染列表项。 1 //自动填充 2 $(function(){ 3 $("#search").keyup(function(){ 4 var url = "productFindByWordServlet"; 5 var word = $(this).val(); 6 if(word == "") { 7 //如果没有输入关键字,隐藏提供区域 8 $("#completeShow").slideUp(200); 9 return false; 10 } 11 var params = {"word":word}; 12 $.post(url,params,function(data){ 13 $("#completeShow").html("<ul id='itemul' class='list-group'></ul>"); 14 for(var i = 0 ; i < data.length ; i ++){ 15 var product = data; 16 //处理关键字显示 17 var str = ""+product.pname + "("+ product.pinyin +")"; 18 $("#itemul").append("<li class='list-group-item'><a href='#'>"+str+"</a></li>"); 19 $("#completeShow").show(); 20 } 21 }); 22 }).focus(function(){ 23 //获得焦点时,如果有搜索项显示 24 if($("#completeShow li").size() > 0){ 25 $("#completeShow").show(); 26 } 27 }).click(function(){ 28 //如果点击的是文本框,阻止点击事件,及不触发document的click事件 29 return false; 30 }); 31 /** 32 * 点击其他位置时,隐藏提示区域 33 */ 34 $(document).click(function(){ 35 $("#completeShow").slideUp(200); 36 }); 37 }); |