每个单词下方的 Jquery-ui 自动完成下拉菜单

标签 jquery jquery-ui autocomplete jquery-ui-autocomplete

我正在使用Autocomplete来自 jquery-ui.在多个值中,您可以在空格后获取每个单词的下拉列表,但下拉列表显示为输入框的大小。是否可以使下拉列表出现在每个下拉列表的光标下方,其宽度等于下拉单词而不是输入框的整个长度?

编辑:示例(类似 Google 的搜索框):

当您进入谷歌并在句子继续时输入一个长句子时,在每个单词之后,光标位置下方的每个单词都会出现一个自动完成下拉列表。所以我需要一个类似的下拉列表,可以将其添加到 jQuery 自动完成

enter image description here

我的函数之所以这么大,是因为它具有多个单词和按字母顺序显示数组的特点。 这是<script代码:

    <script>

    $(function() {

            var availableTags = <?php echo json_encode($sometags); ?>;


            function split( val ) {
            return val.split( / \s*/ );
            }
            function extractLast( term ) {
            return split( term ).pop();
            }
             $( "#query" )
            // don't navigate away from the field on tab when selecting an item
            .bind( "keydown", function( event ) {
            if ( event.keyCode === $.ui.keyCode.TAB &&
            $( this ).data( "autocomplete" ).menu.active ) {
            event.preventDefault();
            }
            })
            .autocomplete({
            minLength: 1,
            source: function( request, response ) {
            // delegate back to autocomplete, but extract the last term
            response( $.ui.autocomplete.filter(
            availableTags, extractLast( request.term ) ) );
            var term = $.ui.autocomplete.escapeRegex(request.term)
            , startsWithMatcher = new RegExp("^" + term, "i")
            , startsWith = $.grep(availableTags, function(value) {
                return startsWithMatcher.test(value.label || value.value || value);
            })
            , containsMatcher = new RegExp(term, "i")
            , contains = $.grep(availableTags, function (value) {
                return $.inArray(value, startsWith) < 0 &&
                    containsMatcher.test(value.label || value.value || value);
            });

            response(startsWith.concat(contains));
            },
            focus: function() {
            // prevent value inserted on focus
            return false;
            },
            select: function( event, ui ) {
            var terms = split( this.value );
            // remove the current input
            terms.pop();
            // add the selected item
            terms.push( ui.item.value );
            // add placeholder to get the comma-and-space at the end
            terms.push( "" );
            this.value = terms.join( " " );
            return false;
            }
            });

    });
    </script>

编辑:就像谷歌框一样,下拉列表应包含在输入框的宽度内,这意味着例如,输入框中最后一个单词的下拉框不应向右调整大小,而应向左调​​整大小。下拉框的右边缘应与输入框的右边缘对齐,并且下拉框的总宽度(如果单词与输入框一样大或大于输入框)不应超过输入框的宽度。

更新: 这是类似谷歌自动完成的最终版本:Fiddle (更新于 16/2/2013)
特点:
1) 修复了多个单词根据建议按字母顺序排序的问题 ( jQuery-ui autocomplete multiple values sort results alphabetically )
2)从2个数组中检索建议,第一个建议以输入框的全宽打开,就像在谷歌中一样,其余建议以最长建议的宽度打开
3) 修复了在输入“空格”后的单词(多个值)之前打开下拉菜单的错误。
4) 防止下拉列表在末尾保持打开状态,同时在中间添加单词。
5) 16/2/2013 更新:当建议框输入的标签长度​​超过输入框的长度,输入下一个标签时,输入框会显示第一个标签或移回第一个标签位置,然后不是从光标上次放置的位置开始,如此处所示 - http://jqueryui.com/autocomplete/#multiple 。此问题已修复。

这是一个类似的 fiddle ,仅使用一个数组,并且建议始终处于最长建议的宽度 - FIDDLE

感谢 Jeffery To 提供了问题的主要解决方案,感谢 Vadim 和 Dom,他们的回答提供了对创建上述 mod 有用的想法。

最佳答案

正如其他答案所建议的,我们测量输入字段中文本的宽度(使用隐藏元素),然后偏移自动完成框。我们还可以重置自动完成框的宽度,使其仅与最长的建议一样宽( demo ):

open: function( event, ui ) {
    var input = $( event.target ),
        widget = input.autocomplete( "widget" ),
        style = $.extend( input.css( [
            "font",
            "border-left",
            "padding-left"
        ] ), {
            position: "absolute",
            visibility: "hidden",
            "padding-right": 0,
            "border-right": 0,
            "white-space": "pre"
        } ),
        div = $( "<div/>" ),
        pos = {
            my: "left top",
            collision: "none"
        },
        offset = -7; // magic number to align the first letter
                     // in the text field with the first letter
                     // of suggestions
                     // depends on how you style the autocomplete box

    widget.css( "width", "" );

    div
        .text( input.val().replace( /\S*$/, "" ) )
        .css( style )
        .insertAfter( input );
    offset = Math.min(
        Math.max( offset + div.width(), 0 ),
        input.width() - widget.width()
    );
    div.remove();

    pos.at = "left+" + offset + " bottom";
    input.autocomplete( "option", "position", pos );

    widget.position( $.extend( { of: input }, pos ) );
}

更新:修复了自动完成框的定位

更新 2:另一个自动完成框定位修复

关于每个单词下方的 Jquery-ui 自动完成下拉菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14672433/

相关文章:

javascript - jquery中如何获取$(this)的特定上层类

jquery - jquery 滚动不会一直向上

javascript - jQuery 在 Firefox 上运行不佳,在 Safari 中根本无法运行

javascript - 检测 jQuery-ui droppable 中 Not Acceptable 拖放

mysql - asp.net 中带有文本和图像的自动完成文本框

jquery-plugins - 选择日期范围后强制 JQuery Datatable 通过 AJAX 加载数据

javascript - 如何通过滚动使标题背景不透明

jQuery UI Slider 检测 slider 处理拖放事件

xml - Visual Studio 2008 自定义配置 xsd intellisense 自动完成损坏!

javascript - 从 phpscript 获取结果后将触发 JQuery 自动完成 keyup 事件