jquery検索ボックス類似プロンプトの実装

11741 ワード

JQueryで実現するGOOGLEBAIDU検索ボックスのようなヒント機能.
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は、テストの便宜上、直接データを返すため、実際のアプリケーションでは
データソースからデータを取り出す.