jsonsuggest是一个不错的js插件,可以实现模糊联想查询,效果如图,
客户体验还是不错,不过我也是弄了一两天,基于我同事修改过的源码之上,我还修改了源码
(function($) { $.fn.jsonSuggest = function(searchData, settings) { var defaults = { minCharacters : 1, maxResults : undefined, wildCard : "", caseSensitive : false, notCharacter : "!", maxHeight : 350, highlightMatches : true, onSelect : undefined, ajaxResults : false, key : "id", value : "name", textId : "" }; settings = $.extend(defaults, settings); return this.each(function() { function regexEscape(txt, omit) { var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\']; if (omit) { for (var i = 0; i < specials.length; i++) { if (specials[i] === omit) { specials.splice(i, 1); } } } var escapePatt = new RegExp('(\\' + specials.join('|\\') + ')', 'g'); return txt.replace(escapePatt, '\\$1'); } var obj = $(this), wildCardPatt = new RegExp( regexEscape(settings.wildCard || ''), 'g'), results = $('<div />'), currentSelection, pageX, pageY; function selectResultItem(item) { $(results).html('').hide(); var tId = settings.textId; $('#' + tId).val(item.name); if (typeof settings.onSelect === 'function') { settings.onSelect(item, settings.textId); } } function setHoverClass(el) { $('div.resultItem', results).removeClass('hover'); $(el).addClass('hover'); currentSelection = el; } function buildResults(resultObjects, sFilterTxt) { var v1 = settings.key; var v2 = settings.value; sFilterTxt = "(" + sFilterTxt + ")"; var bOddRow = true, i, iFound = 0, filterPatt = settings.caseSensitive ? new RegExp(sFilterTxt, "g") : new RegExp(sFilterTxt, "ig"); $(results).html('').hide(); for (i = 0; i < resultObjects.length; i += 1) { var item = $('<div />'), text = resultObjects[i][v1]; // 楂樹寒鏄剧ず 杈撳叆鐨勫瓧绗� // if (settings.highlightMatches === true) { // text = text.replace(filterPatt, // "<strong>$1</strong>"); // } $(item).append('<p class="text">' + text + ':' + resultObjects[i][v2]); $(item).append('</p>'); if (typeof resultObjects[i].image === 'string') { $(item).prepend('<img src="' + resultObjects[i].image + '" />') .append('<br style="clear:both;" />'); } $(item).addClass('resultItem').addClass((bOddRow) ? 'odd' : 'even').click(function(n) { return function() { selectResultItem(resultObjects[n]); }; }(i)).mouseover(function(el) { return function() { setHoverClass(el); }; }(item)); $(results).append(item); bOddRow = !bOddRow; iFound += 1; if (typeof settings.maxResults === 'number' && iFound >= settings.maxResults) { break; } } if ($('div', results).length > 0) { currentSelection = undefined; $(results).show().css('height', 'auto'); if ($(results).height() > settings.maxHeight) { $(results).css({ 'overflow' : 'auto', 'height' : settings.maxHeight + 'px' }); } } } function checkStr(str) { var iu, iuu, regArray = new Array("", "◎", "■", "●", "№", "↑", "→", "↓" + "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "-", "+", "=", "|", "'", "[", "]", "?", "~", "`" + "!", "<", ">", "‰", "→", "←", "↑", "↓", "¤", "§", "#", "&", "&", "\", "≡", "≠" + "≈", "∈", "∪", "∏", "∑", "∧", "∨", "⊥", "∥", "∥", "∠", "⊙", "≌", "≌", "√", "∝", "∞", "∮" + "∫", "≯", "≮", ">", "≥", "≤", "≠", "±", "+", "÷", "×", "/", "Ⅱ", "Ⅰ", "Ⅲ", "Ⅳ", "Ⅴ", "Ⅵ", "Ⅶ", "Ⅷ", "Ⅹ", "Ⅻ", "㈠", "㈡" + "╄", "╅", "╇", "┻", "┻", "┇", "┭", "┷", "┦", "┣", "┝", "┤", "┷", "┷", "┹", "╉", "╇", "【", "】" + "㈢", "㈣", "㈤", "㈥", "㈦", "㈧", "㈨", "㈩", "①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨", "⑩", "┌", "├", "┬", "┼", "┍", "┕", "┗", "┏", "┅", "─" + "〖", "〗", "←", "〓", "☆", "§", "□", "‰", "◇", "︿", "@", "△", "▲", "#", "℃", "※", ".", "≈", "¢"); iuu = regArray.length; for (iu = 1; iu <= iuu; iu++) { if (str.indexOf(regArray[iu]) != -1) { return false; } } return true; } function runSuggest(e) { if (this.value.length < settings.minCharacters) { $(results).html('').hide(); return false; } var resultObjects = [], sFilterTxt = (!settings.wildCard) ? regexEscape(this.value) : regexEscape(this.value, settings.wildCard).replace( wildCardPatt, '.*'), bMatch = true, filterPatt, i; if (settings.notCharacter && sFilterTxt.indexOf(settings.notCharacter) === 0) { sFilterTxt = sFilterTxt.substr( settings.notCharacter.length, sFilterTxt.length); if (sFilterTxt.length > 0) { bMatch = false; } } sFilterTxt = sFilterTxt || '.*'; sFilterTxt = settings.wildCard ? '^' + sFilterTxt : sFilterTxt; filterPatt = settings.caseSensitive ? new RegExp(sFilterTxt) : new RegExp(sFilterTxt, "i"); if (settings.ajaxResults === true) { var JsonURL = searchData(this.value, settings.wildCard, settings.caseSensitive, settings.notCharacter); $.ajaxSetup({ cache : false }); if (checkStr(this.value)) { $.getJSON(JsonURL, function(data) { if (typeof data === 'string') { data = JSON.parse(data); } buildResults(data, sFilterTxt); }); } else { alert("不允许包含非法字符" + this.value); this.value = ""; this.focus(); } } else { for (i = 0; i < searchData.length; i += 1) { if (filterPatt.test(searchData[i].text) === bMatch) { resultObjects.push(searchData[i]); } } } buildResults(resultObjects, sFilterTxt); } function keyListener(e) { switch (e.keyCode) { case 13 : $(currentSelection).trigger('click'); return false; case 40 : if (typeof currentSelection === 'undefined') { currentSelection = $('div.resultItem:first', results).get(0); } else { currentSelection = $(currentSelection).next() .get(0); } setHoverClass(currentSelection); if (currentSelection) { $(results).scrollTop(currentSelection.offsetTop); } return false; case 38 : if (typeof currentSelection === 'undefined') { currentSelection = $('div.resultItem:last', results) .get(0); } else { currentSelection = $(currentSelection).prev() .get(0); } setHoverClass(currentSelection); if (currentSelection) { $(results).scrollTop(currentSelection.offsetTop); } return false; default : runSuggest.apply(this, [e]); } } $(results).addClass('jsonSuggestResults').css({ 'top' : (obj.position().top + obj.height() + 5) + 'px', 'left' : obj.position().left + 'px', 'width' : obj.width() + 'px' }).hide(); obj.after(results).keyup(keyListener).blur(function(e) { var resPos = $(results).offset(); resPos.bottom = resPos.top + $(results).height(); resPos.right = resPos.left + $(results).width(); if (pageY < resPos.top || pageY > resPos.bottom || pageX < resPos.left || pageX > resPos.right) { $(results).hide(); } }).focus(function(e) { $(results).css({ 'top' : (obj.position().top + obj.height() + 5) + 'px', 'left' : obj.position().left + 'px' }); if ($('div', results).length > 0) { $(results).show(); } }).attr('autocomplete', 'off'); $().mousemove(function(e) { pageX = e.pageX; pageY = e.pageY; }); if ($.browser.opera) { obj.keydown(function(e) { if (e.keyCode === 40) { return keyListener(e); } }); } settings.notCharacter = regexEscape(settings.notCharacter || ''); if (!settings.ajaxResults) { if (typeof searchData === 'function') { searchData = searchData(); } if (typeof searchData === 'string') { searchData = JSON.parse(searchData); } } }); }; })(jQuery);
以下是我调用的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>My JSP 'employeelist.jsp' starting page</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"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/jquery.jsonSuggest-dev.js"></script> <script type="text/javascript" src="js/jquery.jsonSuggest.js"></script> <link rel="stylesheet" href="css/jsonSuggest.css" type="text/css"></link> <script type="text/javascript"> $(function (){ $('#empName').jsonSuggest( function(text, wildCard, caseSensitive, notCharacter) { var pin = $("#empName"); var url = "ownerListAction.do?pin="+pin.val(); return url; },{ajaxResults:true,minCharacters:1,key:"ename",value:"eenl",textId:"empName"}); }) </script> </head> <body> <input id="empName" /> </body> </html>