最近在做一個在文本框輸入關鍵字, 文本框下動態顯示加載相關內容的下拉列表的效果, 就是類似於百度和淘寶搜索框這種效果.
不斷的研究加上嘗試, 得到兩種方案解決這個需求, 特意記錄一下, 以免下次用的時候忘記.
方法一: HTML5新增的datalist標簽
HTML5作為當下最為熱門的 Web 技術, 已經在互聯網行業得到了普遍應用, 基於HTML5的瀏覽器和Web引擎為用戶帶來了感知體驗上的巨大飛躍, 並將Web應用帶入了一個新的發展階段, 可以預見HTML5會有更廣泛的使用及更好的發展. HTML5相較於HTML4.01增加了好多實用的語義化標簽和屬性, 關於其中datalist標簽的詳細使用介紹可以參考datalist標簽 | 菜鳥教程.
1.HTML部分代碼
<input id="userName" type="text" autocomplete="off" list="userNameList" placeholder=" 請輸入用戶名" onblur="checkUserName(this)" onfocus="findAllUsers()"> <datalist id="userNameList"></datalist> <label>雙擊文本框進行選擇</label> <input type="hidden" name="userId" />
顯示效果如圖所示
2.JS部分代碼
// "用戶名"模糊匹配查詢_jquery Ajax實現 $(document).ready(function() { $('#userName').keyup(function() { $("#userNameList option").remove(); $.ajaxSetup({async: true}); $.get(webUrl+"/sys/userRole/fuzzySearchUser.action", {'username' : $("#userName").val() == "" ? null : $("#userName").val()}, function(data) { for(var i in data) { /* $("#userNameList").append("<option value=data[i].username data-userId=data[i].id ></option>"); */ var html = ""; html += "<option value='" + data[i].username + "' data-userId='" + data[i].id + "'></option>"; $("#userNameList").append(html); /* console.log(html); */ } }, "json") }) })
當每次在文本框輸入文字並按下鍵盤后, ajax將本文框中的文字傳到后台處理, 並將查到的數據以json格式返回, 再通過拼接字符串將標簽加到中, 顯示如下效果.
注意事項:
1. 上圖是在forfox下的顯示效果, 如果查詢出的結果比較多的話, 會自動添加滾動條; 而chrome則不會出現滾動條, 會顯示所有查詢結果, 我也沒用css修改好, 有時間再試試; 在IE和Edge上, 每次輸入內容后都無法直接顯示出下拉列表, 需要按一下”Backspace”才能顯示, 查看HTML源碼發現datalist標簽下有相應的option內容…..也許是HTML5還太年輕, 各個瀏覽器顯示效果都不同, 折騰好久快要炸了…..
2. HTML data-* 屬性也是HTML5新增的屬性, 用於存儲私有頁面后應用的自定義數據. 其中jquery有個相應的方法data()方法用於在指定的元素上存取數據, 返回設置值. 注意: 自定義屬性前綴 “data-” 會被客戶端忽略.
3. dataList下的option標簽選中的時候沒法選中當前的對象, 並獲取id值, 這里我采用的方式是在提交表單的時候, 將搜索框中的內容和后台返回的值進行對比, 將匹配的值的id傳到設置的隱藏域中, 最后傳到后台. 代碼如下:
var userInfo = $("#userName").val();
var getUserId = $("option[value='" + userInfo + "']").data("userid");
$("input[name='userId']").val(getUserId);
3. 后台Java部分代碼
項目后台是用的SSM框架編寫.
@ResponseBody @RequestMapping("/fuzzySearchUser") public List<SysUser> fuzzySearchUser(SysUser user) { return userRoleService.findUsersByName(user); }
至此, 用datalist標簽基本上能實現要求的功能, 不過在不同瀏覽器顯示效果不同的問題還是沒有完美的解決方案, 為了不耽誤項目進度, 我采用了下列方法二.
方法二 jQuery Autocomplete插件
jQuery Autocomplete 插件根據用戶輸入值進行搜索和過濾,讓用戶快速找到並從預設值列表中選擇。
該插件現在是 jQuery UI 的一部分,獨立的版本不會再更新了。
jQuery UI 實例 - 自動完成(Autocomplete)
jQuery UI API - 自動完成部件(Autocomplete Widget)
1.HTML部分代碼
<input id="rolename" type="text" autocomplete="off" list="roleNameList" placeholder=" 請輸入角色名" > <label>雙擊文本框進行選擇</label> <input type="hidden" name="roleId" />
2.JS部分代碼
// "角色名"模糊匹配查詢 $(document).ready(function(){ $('#rolename').keyup(function(){ $("#roleNameList option").remove(); $.ajax({ async: true, url: webUrl+"/sys/userRole/fuzzySearchRole.action", type: 'get', dataType: 'json', data: { 'name' : $("#rolename").val() == "" ? null : $("#rolename").val(), }, success:function(data) { var arr = []; for(var i in data){ /* var html = ""; html += "<option value='" + data[i].name + "' data-roleId='" + data[i].id + "'></option>"; $("#roleNameList").append(html); */ var one = {}; one.label = data[i].name; one.value = data[i].id; arr[i] = one; /* console.log(one); */ } console.log(arr); $("#rolename").autocomplete({ source : arr, // 數據源 delay: 0, // 多久后顯示, 單位ms width: 320, max: 5, // 為什么不起作用? highlight: false, multiple: true, multipleSeparator: "", scroll: true, scrollHeight: 300, select: function(event, ui){ // 這里的this指向當前輸入框的DOM元素 // event參數是事件對象 // ui對象只有一個item屬性,對應數據源中被選中的對象 alert("123"); /* $(this).value = ui.item.label; */ $( "#rolename" ).val( ui.item.label ); $("input[name='roleId']").val(ui.item.value ); // 必須阻止事件的默認行為,否則autocomplete默認會把ui.item.value設為輸入框的value值 event.preventDefault(); } }); } }) }) })
后台java代碼同上, 就不貼了.
Appache開源項目Lucene
Appache有個全文檢索引擎架構的項目叫”Lucene”, 可以用來做搜索, 改天有空再更.
方案二:
在網上有很多可輸入及模糊查詢的select下拉插件,功能也很強大,比如select、chosen等,做這個的方法也是有很多的,適用自己就好,下面是我自己的一個方法,希望適合大家
CSS代碼
在網上有很多可輸入及模糊查詢的select下拉插件,功能也很強大,比如select、chosen等,做這個的方法也是有很多的,適用自己就好,下面是我自己的一個方法,希望適合大家
.second select {
width: 11%;
height: 106px;
margin: 0px;
outline: none;
border: 1px solid #999;
margin-top: 31px;
}
.second input {
width: 167px;
top: 9px;
outline: none;
border: 0pt;
position: absolute;
line-height: 30px;
left: 8px;
height: 30px;
border: 1px solid #999;
}
.second ul {
position: absolute;
top: 27px;
border: 1px solid #999;
left: 8px;
width: 125px;
line-height: 16px;
}
.ul li{
list-style: none;
width: 161px;
/* left: 15px; */
margin-left: -40px;
font-family: 微軟雅黑;
padding-left: 4px;
}
.blue {
background:#1e91ff;
}
JS代碼
var TempArr=[];//存儲option $(function(){ /*先將數據存入數組*/ $("#typenum option").each(function(index, el) { TempArr[index] = $(this).text(); }); $(document).bind('click', function(e) { var e = e || window.event; //瀏覽器兼容性 var elem = e.target || e.srcElement; while (elem) { //循環判斷至跟節點,防止點擊的是div子元素 if (elem.id && (elem.id == 'typenum' || elem.id == "makeupCo")) { return; } elem = elem.parentNode; } $('#typenum').css('display', 'none'); //點擊的不是div或其子元素 }); }) function changeF(this_) { $(this_).prev("input").val($(this_).find("option:selected").text()); $("#typenum").css({"display":"none"}); } function setfocus(this_){ $("#typenum").css({"display":""}); var select = $("#typenum"); for(i=0;i<TempArr.length;i++){ var option = $("<option></option>").text(TempArr[i]); select.append(option); } } function setinput(this_){ var select = $("#typenum"); select.html(""); for(i=0;i<TempArr.length;i++){ //若找到以txt的內容開頭的,添option if(TempArr[i].substring(0,this_.value.length).indexOf(this_.value)==0){ var option = $("<option></option>").text(TempArr[i]); select.append(option); } } }
頁面代碼
<span class="second"> <input type="text" name="makeupCo" id="makeupCo" class="makeinp" onfocus="setfocus(this)" oninput="setinput(this);" placeholder="請選擇或輸入"/> <select name="makeupCoSe" id="typenum" onchange="changeF(this)" size="10" style="display:none;"> <option value="">1</option> <option value="">2</option> <option value="">12323</option> <option value="">31</option> <option value="">1332</option> <option value="">412</option> <option value="">42</option> <option value="">11</option> </select> </span>
搜索框模糊匹配下拉顯示
最近在做一個在文本框輸入關鍵字, 文本框下動態顯示加載相關內容的下拉列表的效果, 就是類似於百度和淘寶搜索框這種效果.
不斷的研究加上嘗試, 得到兩種方案解決這個需求, 特意記錄一下, 以免下次用的時候忘記.
方法一: HTML5新增的datalist標簽
HTML5作為當下最為熱門的 Web 技術, 已經在互聯網行業得到了普遍應用, 基於HTML5的瀏覽器和Web引擎為用戶帶來了感知體驗上的巨大飛躍, 並將Web應用帶入了一個新的發展階段, 可以預見HTML5會有更廣泛的使用及更好的發展. HTML5相較於HTML4.01增加了好多實用的語義化標簽和屬性, 關於其中datalist標簽的詳細使用介紹可以參考datalist標簽 | 菜鳥教程.
1.HTML部分代碼
<input id="userName" type="text" autocomplete="off" list="userNameList" placeholder=" 請輸入用戶名" onblur="checkUserName(this)" onfocus="findAllUsers()">
<datalist id="userNameList"></datalist>
<label>雙擊文本框進行選擇</label>
<input type="hidden" name="userId" />
- 1
- 2
- 3
- 4
顯示效果如圖所示
2.JS部分代碼
// "用戶名"模糊匹配查詢_jquery Ajax實現
$(document).ready(function() {
$('#userName').keyup(function() {
$("#userNameList option").remove();
$.ajaxSetup({async: true});
$.get(webUrl+"/sys/userRole/fuzzySearchUser.action", {'username' : $("#userName").val() == "" ? null : $("#userName").val()}, function(data) {
for(var i in data) {
/* $("#userNameList").append("<option value=data[i].username data-userId=data[i].id ></option>"); */
var html = "";
html += "<option value='" + data[i].username + "' data-userId='" + data[i].id + "'></option>";
$("#userNameList").append(html);
/* console.log(html); */
}
}, "json")
})
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
當每次在文本框輸入文字並按下鍵盤后, ajax將本文框中的文字傳到后台處理, 並將查到的數據以json格式返回, 再通過拼接字符串將標簽加到中, 顯示如下效果.
注意事項:
1. 上圖是在forfox下的顯示效果, 如果查詢出的結果比較多的話, 會自動添加滾動條; 而chrome則不會出現滾動條, 會顯示所有查詢結果, 我也沒用css修改好, 有時間再試試; 在IE和Edge上, 每次輸入內容后都無法直接顯示出下拉列表, 需要按一下”Backspace”才能顯示, 查看HTML源碼發現datalist標簽下有相應的option內容…..也許是HTML5還太年輕, 各個瀏覽器顯示效果都不同, 折騰好久快要炸了…..
2. HTML data-* 屬性也是HTML5新增的屬性, 用於存儲私有頁面后應用的自定義數據. 其中jquery有個相應的方法data()方法用於在指定的元素上存取數據, 返回設置值. 注意: 自定義屬性前綴 “data-” 會被客戶端忽略.
3. dataList下的option標簽選中的時候沒法選中當前的對象, 並獲取id值, 這里我采用的方式是在提交表單的時候, 將搜索框中的內容和后台返回的值進行對比, 將匹配的值的id傳到設置的隱藏域中, 最后傳到后台. 代碼如下:
var userInfo = $("#userName").val();
var getUserId = $("option[value='" + userInfo + "']").data("userid");
$("input[name='userId']").val(getUserId);
- 1
- 2
- 3
3. 后台Java部分代碼
項目后台是用的SSM框架編寫.
@ResponseBody
@RequestMapping("/fuzzySearchUser")
public List<SysUser> fuzzySearchUser(SysUser user) {
return userRoleService.findUsersByName(user);
}
- 1
- 2
- 3
- 4
- 5
至此, 用datalist標簽基本上能實現要求的功能, 不過在不同瀏覽器顯示效果不同的問題還是沒有完美的解決方案, 為了不耽誤項目進度, 我采用了下列方法二.
方法二 jQuery Autocomplete插件
jQuery Autocomplete 插件根據用戶輸入值進行搜索和過濾,讓用戶快速找到並從預設值列表中選擇。
該插件現在是 jQuery UI 的一部分,獨立的版本不會再更新了。
jQuery UI 實例 - 自動完成(Autocomplete)
jQuery UI API - 自動完成部件(Autocomplete Widget)
1.HTML部分代碼
<input id="rolename" type="text" autocomplete="off" list="roleNameList" placeholder=" 請輸入角色名" >
<label>雙擊文本框進行選擇</label>
<input type="hidden" name="roleId" />
- 1
- 2
- 3
2.JS部分代碼
// "角色名"模糊匹配查詢
$(document).ready(function(){
$('#rolename').keyup(function(){
$("#roleNameList option").remove();
$.ajax({
async: true,
url: webUrl+"/sys/userRole/fuzzySearchRole.action",
type: 'get',
dataType: 'json',
data: {
'name' : $("#rolename").val() == "" ? null : $("#rolename").val(),
},
success:function(data) {
var arr = [];
for(var i in data){
/* var html = ""; html += "<option value='" + data[i].name + "' data-roleId='" + data[i].id + "'></option>"; $("#roleNameList").append(html); */
var one = {};
one.label = data[i].name;
one.value = data[i].id;
arr[i] = one;
/* console.log(one); */
}
console.log(arr);
$("#rolename").autocomplete({
source : arr, // 數據源
delay: 0, // 多久后顯示, 單位ms
width: 320,
max: 5, // 為什么不起作用?
highlight: false,
multiple: true,
multipleSeparator: "",
scroll: true,
scrollHeight: 300,
select: function(event, ui){
// 這里的this指向當前輸入框的DOM元素
// event參數是事件對象
// ui對象只有一個item屬性,對應數據源中被選中的對象
alert("123");
/* $(this).value = ui.item.label; */
$( "#rolename" ).val( ui.item.label );
$("input[name='roleId']").val(ui.item.value );
// 必須阻止事件的默認行為,否則autocomplete默認會把ui.item.value設為輸入框的value值
event.preventDefault();
}
});
}
})
})
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
后台java代碼同上, 就不貼了.
Appache開源項目Lucene
Appache有個全文檢索引擎架構的項目叫”Lucene”, 可以用來做搜索, 改天有空再更.