JQuery UI组合框自动补全功能改进版(即时全部显示+input内容保存)

JQuery UI Autocomplete(自动补全)功能在input前端设计中非常有用,最近一个项目正好用到,仔细研究了下组合框(combobox)的自动补全部分,官方地址是:https://jqueryui.com/autocomplete/#combobox

官方的功能需要一个额外下拉按钮才能显示全部option选项,有些画蛇添足。我的需求是,只要点击输入框,就要显示全部的option选项,并且在输入框里面同时能实现搜索,下面是改进版的功能:

  • 官方 combobox 自动补全的全部功能(除了下拉的按钮)
  • 自动存储input的值,刷新后保存选择值。注意,要使用存储功能,必须设置 select 的 name 属性
  • 点击输入框显示全部备选项(不需要下拉按钮)
  • 设置了option value则选择结果为value,否则为标签内HTML内容
  • 匹配元素 class,可以设置任意多输入框

不多说,直接上源码:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>jQuery UI 自动完成(Autocomplete) - 组合框(Combobox)</title>
    <link rel="stylesheet" href="http://lib.sinaapp.com/js/jquery-ui/1.10.2/themes/smoothness/jquery-ui.min.css">
    <script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
    <script src="http://lib.sinaapp.com/js/jquery-ui/1.10.2/jquery-ui.min.js"></script>

    <script>
    (function( $ ) {
        $.widget( "custom.combobox", {
            _create: function() {
                this.wrapper = $( "<span>" )
                    .addClass( "custom-combobox" )
                    .insertAfter( this.element );

                this.element.hide();
                this._createAutocomplete();
                this._clickShowAll();
            },
            
            // 自动补全主功能          
            _createAutocomplete: function() {
                var select = this.element,
                    option = select.children( "option" ),
                    selectName = select.attr("name"),
                    have = false;

                // 如果设置了select 的name属性,则检查保存数据与页面option是否匹配
                if (selectName){
                    var localValue = localStorage.getItem(selectName);
                    option.each(function(){
                        var itemValue = $(this).val();
                        if (itemValue === localValue)
                        {
                            $(this).attr("selected", "selected");
                            have = true;
                            return false;
                        }
                    });

                    // 如果没有,则新建一个option标签
                    if ( !have )
                    {
                        $( "<option>" ).appendTo( select )
                            .val( localValue )
                            .text( localValue )
                            .attr("selected", "selected");
                    }
                }

                // option selected 标签的值
                var selected = select.children( ":selected" ),
                    value = selected.val();

                // 增加 input 标签,并设置属性
                this.input = $( "<input>" )
                    .appendTo( this.wrapper )
                    .val( value )
                    .attr({ title: ""})
                    .addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
                    .autocomplete({
                        delay: 0,
                        minLength: 0,
                        source: $.proxy( this, "_source" )
                    })
                    .tooltip({
                        tooltipClass: "ui-state-highlight"
                    });

                this._on( this.input, {
                    autocompleteselect: function( event, ui ) {
                        ui.item.option.selected = true;
                        this._trigger( "select", event, {
                            item: ui.item.option
                        });
                    },
     
                    autocompletechange: "_removeIfInvalid"
                });

            },

            // 点击输入框自动显示所有值
            _clickShowAll: function() {
                var input = this.input,
                wasOpen = false;

                input
                .mousedown(function() {
                    wasOpen = input.autocomplete( "widget" ).is( ":visible" );
                })
                .click(function() {
                    input.focus();
                        // 如果已经可见则关闭
                        if ( wasOpen ) {
                        return;
                    }
                    // 传递空字符串作为搜索的值,显示所有的结果
                    input.autocomplete( "search", "" );
                });
            },

            // 获取子标签的内容
            _source: function( request, response ) {
                var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" ),
                    option = this.element.children( "option" );
                response( option.map(function() {
                    var text = $( this ).text(),
                        val = $( this ).val();
                    if ( this.value && ( !request.term || matcher.test(text) ) )
                    return {
                        label: text,
                        value: val,
                        option: this
                    };
                }));
            },

            // 选择之后执行这里 
            _removeIfInvalid: function( event, ui ) {

                var selectName = this.element.attr("name"),
                value = this.input.val(),
                valueLowerCase = value.toLowerCase(),
                valid = false,
                // 是否进行检测,如果不检测输入内容的合法性,将该值设置为 true 即可
                checkInvalid = false;

                // 保存数据
                this.saveData = function() {
                    // 如果设置了select的name属性
                    if (selectName){
                        // 存储数据到localStorage
                        localStorage.setItem(selectName, value);
                    }
                }

                // 如果是直接从下拉菜单中选择,或者配置为不进行数据检测,则直接保存数据,并中断执行 
                if(ui.item || !checkInvalid){
                    this.saveData();
                    return;
                } else {
                    // 搜索一个匹配(不区分大小写)
                    this.element.children( "option" ).each(function() {
                        if ( $( this ).text().toLowerCase() === valueLowerCase ) {
                            this.selected = valid = true;
                            return false;
                        }
                    });

                    // 如果检测通过,则保存数据并中断执行
                    if ( valid ) {
                        this.saveData();
                        return;
                    }

                    // 过滤无效的值功能
                    this.input
                        .val( "" )
                        .attr( "title", value + " 未找到任何结果" )
                        .tooltip( "open" );
                    this.element.val( "" );
                    this._delay(function() {
                            this.input.tooltip( "close" ).attr( "title", "" );
                        }, 2500 );
                    this.input.data( "ui-autocomplete" ).term = "";
                    // 清除存储的数据
                    localStorage.setItem(selectName, "");
                }
            },

            _destroy: function() {
                this.wrapper.remove();
                this.element.show();
            }

        });
    })( jQuery );
     
    $(function() {
        $( ".combobox" ).combobox();
    });
    </script>
</head>
<body>
 
<div class="ui-widget">
    <label>您喜欢的编程语言:</label>
    <!-- 注意,如果要保存数据,必须设置select的name属性,多个select时name属性应该是相互不一样的 -->
    <select class="combobox" name="lang">
        <option value="">请选择...</option>
        <option value="ActionScript">ActionScript</option>
        <option value="AppleScript">AppleScript</option>
        <!-- 如果不设置value,则会返回option标签中的内容 --> 
        <option>Asp</option>
        <option value="BASIC">BASIC</option>
        <option value="C">C</option>
        <!-- 如果value值和HTML内容不同,点选后会返回value值; -->
        <option value="CPP">C++</option>
        <option value="Clojure">Clojure</option>
        <option value="COBOL">COBOL</option>
        <option value="ColdFusion">ColdFusion</option>
        <option value="Erlang">Erlang</option>
        <option value="Fortran">Fortran</option>
        <option value="Groovy">Groovy</option>
        <option value="Haskell">Haskell</option>
        <option value="Java">Java</option>
        <option value="JavaScript">JavaScript</option>
        <option value="Lisp">Lisp</option>
        <option value="Perl">Perl</option>
        <option value="PHP">PHP</option>
        <option value="Python">Python</option>
        <option value="Ruby">Ruby</option>
        <option value="Scala">Scala</option>
        <option value="Scheme">Scheme</option>
    </select>
</div>

</body>
</html>

因为JqueryJquery UIJquery UI CSS直接使用新浪SAE,所以保存以上代码成一个html文件,然后直接打开就可以看到效果了,如下图:

JQuery自动补全功能

在输入框里面输入任何内容,然后鼠标点击页面的其他任意位置,这个值就会保存起来了(在本地 localStorage 中)。刷新页面,还是原来保存的内容。YES。。

« »

4条评论

a
autocomplete says: 回复

实现一个智能提示功能需要ajax、数据库、jsp/php很多知识,
如果数据量大还需要特殊优化
一个小功能,花费太大精力不合适
我使用了92find com的搜索框智能提示功能,只要一行javascript
代码就可以实现baidu、淘宝搜索框提示的全部功能了
比如:拼音匹配、拼音前缀匹配、模糊搜索、智能容错,还可以自定义提示词汇的排序权重
五分钟就可以在线配置拥有主流搜索引擎都有的提示功能

歪麦 says:

赞一个,加油!

a
autocomplete says:

谢谢你的关注,你的网站做的很整洁,我也很喜欢这种风格,是你自己做的吗。我们有机会合作吗 pangjiale@126.com

歪麦 says:

主题是用现成的^_^,内容合适当然要合作呀

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *