实现类似于百度实时搜索将结果在下拉框中显示的功能

本文主要实现一个类似于百度搜索一样,当在输入框中输入内容实时向后台发送请求,并将返回的内容在输入框下面用下拉框的形式显示出来的功能。

由于本人是前端程序员,so,这里只介绍前端实现部分,实现分为HTML,JS两部分(后台对接使用的是PHP):

HTML:

  第一步:封装一个组件用于页面实现

 1 /**
 2      * Print a FilterlistDiv
 3      *
 4      * @param  string $name 表单提交的字段name
 5      * @param  string $value 表单提交的value
 6      * @param  string $searchInputId  输入框id
 7      * @param  string $inputVal  输入框value
 8      * @param  string $filterDivId
 9      * @param  string $class
10      * @param  string $inputPlaceholder
11      * @param  string $searchInputName 需要提交的input的name属性
12      * @access public
13      * @return string
14      */
15      public static function searchFilterInput($name, $value, $searchInputId, $inputVal = '', $class = '', $inputPlaceholder = '', $searchInputName = '')
16      {
17         $html = '';
18         $html .= html::input($name, $value, "class='hidden'");
19         $html .= html::input($searchInputName, $inputVal, "id='{$searchInputId}' placeholder='{$inputPlaceholder}' class='form-control {$class}'");
20         $html .= "<div class='inputFilter'></div>"; 21 22 return $html; 23 }

  第二步:页面调用该组件

1 // 页面调用
2 echo html::searchFilterInput('trader',  '' ,'traderInput', '', '', , );

JS部分:

  第一步:通过扩展jQuery的方式将该方法进行封装,主要包含实时请求事件以及键盘操作事件,该方法根据传入的参数来进行不同的处理,主要处理的参数有:1.url:搜索数据的url;2.getAll:用于标示若输入为空时是否显示所有数据(适用于数据列表少的数据,类似于select下拉框);3.canAdd:用于标识当输入的信息搜索不到时是否允许用户将该信息作为新的数据添加进来。在进行实时请求中,使用setTimeout来进行节流,防止向后台请求频率过多。

  1 +function($, window, document, Math)
  2 {
  3     'use strict';
  4 
  5     var searchFilter = function(element, options)
  6     {
  7         this.$            = $(element); 8 this.options = this.getOptions(options); 9 this.$next = this.$.next(); 10 11 this.init(); 12  }; 13 14 searchFilter.prototype.getOptions = function (options) 15  { 16 options = $.extend({}, searchFilter.DEFAULTS, this.$.data(), options); 17 return options; 18  }; 19 20 searchFilter.prototype.init = function() 21  { 22 //绑定事件 23 this.bindEvents(); 24  }; 25 26 searchFilter.prototype.bindEvents = function() 27  { 28 var $this = this.$, 29 $next = this.$next, 30 url = this.options.url, 31 getAll= this.options.getAll, 32 cantFindInfo = this.options.cantFindInfo ? this.options.cantFindInfo : '', 33 canAdd= this.options.canAdd; 34 35 var focus = function(){ 36 if($next.find('ul li').length > 1) 37  { 38 $next.width($this.width()+20); 39  $next.show(); 40  } 41 42 // 通过仓库动态加载货位 43 if($this.attr('id') == 'shelfInput'){ 44 var store = $this.parents('#selectPosition').find('#store').val(); 45 url = createLink('store', 'getShelvesBySearch', 'storeId='+store); 46  } 47 48 $this.unbind('input propertychange'); 49 $this.bind('input propertychange', change); 50 if(getAll){ 51 getListByInput($this.val()); 52  } 53 else if($this.val() !== '' && $next.find("li").length == 0){ 54 getListByInput($this.val()); 55  } 56  } 57 58 var blur = function(){ 59 setTimeout(function(){ 60  $next.hide(); 61 $this.prev().val(''); 62 if($this.val() !== '') 63  { 64 var lis = $next.find("li"); 65 for(var i = 0; i < lis.length; i++){ 66 if($this.val() == lis[i].innerText){ 67 $this.prev().val($(lis[i]).attr('id')); 68 break; 69  } 70  } 71 72 if($this.prev().val() == '' && !canAdd){ 73 $this.val(''); 74  } 75  } 76 },200); 77  } 78 79 var change = function(){ 80 if($this.val() != '' || getAll){ 81 $next.width($this.width()+20); 82  $next.show(); 83 setTimeout(function(){getListByInput($this.val())}, 300); 84  } 85  } 86 87 var keydown = function(){ 88 var key = event.keyCode, 89 searchNum = $next.find("li").length, // 搜索到的相关条数 90 li = $next.find("li.active-item"), // 当前通过键盘选中的是第几条li 91 index = $next.find('li').index(li); 92 93 switch(key) 94  { 95 case 13: // 回车键 96  event.preventDefault(); 97 if(li.attr('id')) { 98 selectOptionToInput(li.attr('id'), li.text()); 99  } 100  $next.hide(); 101 break; 102 case 38: // 上键 103  event.stopPropagation(); 104  event.preventDefault(); 105 if(index >= 0) 106  { 107 index--; 108 if (index == -1){ 109 if(canAdd) $next.find("li").removeClass('active-item'); 110 else index = 0; //到顶了 111  } 112 113 // 使选中的焦点永远能看到 114 var $currLi = $next.find("li:eq(" + index + ")"), 115 $contanier = $currLi.closest('.inputFilter'); 116 117 if($currLi.position().top <= 20 ) 118  { 119 $contanier.scrollTop($contanier.scrollTop() - $currLi.height()); 120  } 121  } 122 123 break; 124 case 40: // 下键 125  event.stopPropagation(); 126  event.preventDefault(); 127  $next.show(); 128 index++; 129 130 if (index == searchNum) index = searchNum - 1; //到底了 131 132 // 使选中的焦点永远能看到 133 var $currLi = $next.find("li:eq(" + index + ")"), 134 $contanier = $currLi.closest('.inputFilter'); 135 136 if(($currLi.position().top + $currLi.height() + 20) > $contanier.height()) 137  { 138 $contanier.scrollTop($contanier.scrollTop() + $currLi.height()); 139  } 140 141 break; 142 default: break; 143  } 144 if(index >= 0){ 145 li = $next.find("li:eq(" + index + ")"); 146 li.addClass("active-item").siblings().removeClass('active-item'); 147  } 148  } 149 150 var getListByInput = function(value) 151  { 152  $.ajax({ 153 type: "POST", 154 data: {"value": value}, 155  url : url, 156 dataType:'json', 157 success:function(data){ 158 var searchList = "<ul>"; 159 160 if(!isEmptyObj(data)) 161  { 162 for(var key in data){ 163 var li = "<li id='" + key + "'>" + data[key] + "<b></b></li>"; 164 searchList += li; 165  } 166 } else { 167 searchList += "<li>" + cantFindInfo + "</li>"; 168  } 169 170 searchList += "</ul>"; 171 172 // 重新加载下拉列表 173 $next.find('ul').remove(); 174  $next.append(searchList); 175 $next.find('li').each(function(i,e){ 176 $(e).on('click',function(){ 177 selectOptionToInput($(this).attr('id'), $(this).text()); 178  }); 179  }); 180 181 // 若没有显示下拉框则显示下拉框 182 if(getAll && $next.find('ul li').length > 1){ 183 $next.width($this.width()+20); 184  $next.show(); 185  } 186 if(!canAdd){ 187 $next.find("li:eq(0)").addClass('active-item'); 188  } 189  }, 190 error:function(message){ 191  } 192  }); 193  } 194 195 var selectOptionToInput = function(id, name) 196  { 197 var $prev = $this.prev(); 198 199 $this.val(name); 200  $prev.val(id); 201  $prev.change(); 202 $next.find('li#'+id).addClass('active-item').siblings().removeClass('active-item'); 203  } 204 205 this.$.on('focus', focus); 206 this.$.on('keydown', keydown); 207 this.$.on('blur', blur); 208 if($this.is(":focus")){ 209 $this.bind('input propertychange', change); 210  } 211  } 212 213 $.fn.searchFilter = function(option) 214  { 215 return this.each(function() 216  { 217 var $this = $(this); 218 var data = $this.data('zui.searchFilter'); 219 var options = typeof option == 'object' && option; 220 221 if (!data) $this.data('zui.searchFilter', (data = new searchFilter(this, options))); 222 223 if (typeof option == 'string') data[option](); 224  }) 225  }; 226 227 $.fn.searchFilter.Constructor = searchFilter; 228 }(jQuery,window,document,Math);

  第二步:调用searchFilter方法

1  $('#traderInput').searchFilter({url: getTraderUrl, cantFindInfo: “无法找到该信息”}); 

 

 

  

转载于:https://www.cnblogs.com/hbujt/p/4872707.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值