jquery实现搜索框类似提示功

用JQuery实现的类似GOOGLE\BAIDU搜索框的提示功能.

autopoint.js代码:

/*
 *    @author: 范永强
 *    Depends:
 *        jquery.js
 *
 *    function:类似GOOGLE搜索框提示功能
 *    use:$("#input1, #input2").autopoint({url:"url", submit:["submit1", "submit2"]});
 *        对所有需要自动提示功能的输入框对象使用autopoint方法,
 *        url为ajax提交的url,submit为输入框enter键提交的action
*/
(function($) {
    $.fn.autopoint = function (options) {
        var bt = $.browser;
        //根据浏览器设定不同属性
        dialect = bt.msie?{
            topoffset:5,//提示框top属性与输入框偏移
            widthoffset:6//提示框width属性与输入框偏移    
        }:bt.mozilla?{
            topoffset:5,
            widthoffset:2
        }:bt.safari?{
            topoffset:6,
            widthoffset:2
        }:bt.opera?{
            topoffset:5,
            widthoffset:2
        }:{
            topoffset:5,
            widthoffset:2
        };
        defaults = {
                url:options.url,
                keyUp : 38,//向上方向键
                keyDown : 40,//向下方向键
                keyEnter : 13,//回车键
                listHoverCSS : 'jhover',//提示框列表鼠标悬浮的样式
                tpl : '<div class="list"><div class="word">{word}</div><div class="view">{view}</div></div>',
                   submit:options.submit
        };
        var originalVal = new Array();
        var lastVal = new Array();
        var options = $.extend(defaults, $.extend(dialect, options));
        var dropDiv = $('<div></div>').addClass('dropDiv').appendTo('body');
        return this.each(function(i){
            var pa = $(this);
            $(this).bind('keydown', function(event){
                if (dropDiv.css('display') != 'none') {//当提示层显示时才对键盘事件处理
                    var currentList = dropDiv.find('.' + options.listHoverCSS);
                    if (event.keyCode == options.keyDown) {//如果按的是向下方向键
                        if (currentList.length == 0) {
                            originalVal[i] = $(this).val();
                            //如果提示列表没有一个被选中,则将列表第一个选中
                            $(this).val(getPointWord(dropDiv.find('.list:first')
                                    .mouseover()));
                        } else if (currentList.next().length == 0) {
                            //如果是最后一个被选中,则取消选中,即可认为是输入框被选中
                            unHoverAll();
                            $(this).val(originalVal[i]);
                        } else {
                            unHoverAll();
                            //将原先选中列的下一列选中
                            if (currentList.next().length != 0)
                                $(this).val(getPointWord(currentList.next()
                                        .mouseover()));
                        }
                        return false;
                    } else if (event.keyCode == options.keyUp) {//如果按的是向上方向键
                        if (currentList.length == 0) {
                            originalVal[i] = $(this).val();
                            $(this).val(getPointWord(dropDiv.find('.list:last')
                                    .mouseover()));
                        } else if (currentList.prev().length == 0) {
                            unHoverAll();
                            $(this).val(originalVal[i]);
                        } else {
                            unHoverAll();
                            if (currentList.prev().length != 0)
                                $(this).val(getPointWord(currentList.prev()
                                        .mouseover()));
                        }
                        return false;
                    }else if(event.keyCode == options.keyEnter) {
                        //console.debug(currentList.length);
                        if(currentList.length == 0) 
                            if(options.submit[i]) {
                                $('#'+options.submit[i]).submit();
                            }
                        dropDiv.empty().hide();
                        return;
                    }
                }else if(event.keyCode == options.keyEnter)
                    //console.debug(options.submit[i]);
                    if(options.submit[i]) {
                        $('#'+options.submit[i]).submit();
                        return;
                    }
            }).bind('keyup', function(event){
                //输入框值没有改变返回
                if ($(this).val() == lastVal[i])
                    return;
                //当按键弹起记录输入框值,以方便查看键值有没有变
                lastVal[i] = $(this).val();
                //输入框值变为空返回
                if($(this).val() == ''){
                    dropDiv.empty().hide();
                    return;
                }
                //如果按下的向上或是向下键,说明在选择
                if(event.keyCode == options.keyUp||event.keyCode == options.keyDown) return;
                //输入框中值有变化,发送请求
                getData(pa, $(this).val());
            }).bind('blur', function(){
                //输入框失去焦点隐藏提示框,mousedown比
                //blur优先触发所以先处理选择提示框的内容
                dropDiv.empty().hide();
            });
            
            /**处理ajax返回成功的方法**/
            handleResponse = function(parent, json) {
                var isEmpty = true;
                for(var o in json){
                    if(o == 'data') isEmpty = false;
                }
                if(isEmpty) {
                    //showError("返回数据格式错误,请检查请求URL是否正确!");
                    dropDiv.empty().hide();
                    return;
                }
                if(json['data'].length == 0) {
                    //返回数据为空
                    dropDiv.empty().hide();
                    return;
                }
                refreshDropDiv(parent, json);
                dropDiv.show();
            };
            /**处理ajax失败的方法**/
            handleError = function(error) {
                dropDiv.empty().hide();
                showError("请求失败!"+arguments[1]);
            };
            showError = function(error){
                //alert(error);
            };
            /**通过ajax返回json格式数据生成用来创建dom的字符串**/
            render = function(parent, json) {
                var res = json['data'] || json;
                var appendStr = '';
                //用json对象中内容替换模版字符串中匹配/\{([a-z]+)\}/ig的内容,如{word},{view}
                for ( var i = 0; i < res.length; i+=1) {
                    appendStr += options.tpl.replace(/\{([a-z]+)\}/ig, function(m, n) {
                        return res[i][n];
                    });
                }
                jebind(parent, appendStr);
            };
            /**将新建dom对象插入到提示框中,并重新绑定mouseover事件监听**/
            jebind = function(parent, a) {
                dropDiv.append(a);
                dropDiv.find('.list').each(function() {
                    $(this).unbind('mouseover').mouseover(function() {
                        unHoverAll();
                        $(this).addClass(options.listHoverCSS);
                    }).unbind('mousedown').mousedown(function(){
                        parent.val(getPointWord($(this)));
                        dropDiv.empty().hide();
                        parent.focus();
                    });
                });
            };
            /**将提示框中所有列的hover样式去掉**/
            unHoverAll = function() {
                dropDiv.find('.list').each(function() {
                    $(this).removeClass(options.listHoverCSS);
                });
            };
            /**在提示框中取得当前选中的提示关键字**/
            getPointWord = function(p) {
                return p.find('div:first').text();
            };
            /**刷新提示框,并设定样式**/
            refreshDropDiv = function(parent, json) {
                var left = parent.offset().left;
                var height = parent.height();
                var top = parent.offset().top + options.topoffset + height;
                var width = options.width || (parent.width()+options.widthoffset) + 'px';
                dropDiv.empty();
                dropDiv.css( {
                    //'border' : '1px solid #999',
                    'left' : left,
                    'top' : top,
                    'width' : width
                });
                render(parent, json);
                //防止ajax返回之前输入框失去焦点导致提示框不消失
                parent.focus();
            };
            /**通过ajax向服务器请求数据**/
            getData = function(parent, word) {
                $.ajax( {
                    type : 'POST',
                    data : {word:word,rand:Math.random()},
                    url : options.url,
                    dataType : 'json',
                    timeout : 1000,
                    success : function(json){handleResponse(parent, json);},
                    error : handleError
                });
            };
        });
      };
})(jQuery);
使用方法:

<style type="text/css">
.dropDiv {
    position: absolute;
    z-index: 10;
    display: none;
    cursor: hand;
    border:1px solid #7F9DB9;
}

.dropDiv .jhover {
    background-color: #D5E2FF;
}
.dropDiv .list {
    float:left;
    width:100%;
}
.dropDiv .word {
float:left;
}

.dropDiv .view {
float:right;
color: gray;
text-align: right;
font-size: 10pt;
}
</style>
<script type="text/javascript" src="../js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="../js/autopoint.js"></script>
<script type="text/javascript">
$(function(){
$("input").autopoint({url:'http://localhost/xun/ajax.svl?method=getsearchhelp',submit:["action1", "action2"]});
});
</script>
</head>
<body>
<input type="text" id="search" name="search" size="50" autocomplete="off">
        <br />
        <br />
        <br />
        <br />
        <br />
<input type="text" size="50" autocomplete="off" />
</body>

servlet主要部分:

 1 response.setContentType("text/html");  
 2         response.setHeader("Cache-Control", "no-cache");  
 3         response.setCharacterEncoding("UTF-8");
 4         String word = request.getParameter("word");
 5         if(Utils.isBlank(word)) return;
 6         JSONObject json = new JSONObject();
 7         JSONArray array = new JSONArray();
 8         Map<String, Object> map1 = new HashMap<String, Object>();
 9         map1.put("word", word + "a1");
10         map1.put("view", 10);
11         Map<String, Object> map2 = new HashMap<String, Object>();
12         map2.put("word", word + "a2");
13         map2.put("view", 15);
14         Map<String, Object> map3 = new HashMap<String, Object>();
15         map3.put("word", word + "a3");
16         map3.put("view", 2);
17         array.add(JSONObject.fromObject(map1));
18         array.add(JSONObject.fromObject(map2));
19         array.add(JSONObject.fromObject(map3));
20         json.put("data", array);
21         PrintWriter out = response.getWriter();
22         out.print(json.toString());
23         out.close();

其中JSONObject和JSONArray类来自json-lib.jar,为了测试方便,是直接返回数据的,实际应用中可以替换为

从数据源查取数据.



posted @ 2012-07-04 18:11  范永强  阅读(147)  评论(0编辑  收藏  举报