12

jquery-ui のオートコンプリートを使用しています。複数の値では、スペースの後に単語ごとにドロップダウン リストを取得できますが、ドロップダウンは入力ボックスのサイズで表示されます。入力ボックスの全長ではなく、ドロップダウンの単語に相当する幅を持つそれぞれのカーソルの下にドロップダウンを表示することは可能ですか?

編集: 例 (Google のような検索ボックス):

Google にアクセスして長い文章を入力すると、各単語の後に、カーソル位置の下の単語ごとにオートコンプリート ドロップダウンが表示されます。したがって、jQuery Autocomplete に追加できる同様のドロップダウンが必要です

ここに画像の説明を入力

私の関数は、複数の単語とアルファベット順に配列を表示する機能を備えているため、これほど大きなものです。<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>

編集: google-box と同様に、ドロップダウンは入力ボックスの幅内に収まる必要があります。たとえば、入力ボックスの最後の単語のドロップダウン ボックスは、右ではなく左にサイズ変更する必要があります。ドロップダウン ボックスの右端は、入力ボックスの右端と一致する必要があり、ドロップダウンの合計幅 (入力ボックスと同じかそれより大きい単語の場合) は、入力ボックスの幅を超えないようにする必要があります。

更新: Googleのようオートコンプリートの 最終的な mod は次 のとおり です
。Google のように最初の提案が入力ボックスの全幅で開き、残りの提案が最長の提案の幅で開く 2 つの配列 3) 「スペース」(複数の値) の後に単語を入力する前にドロップダウンを開くバグを修正しました。 4) 間に単語を追加している間、ドロップダウンが最後に開いたままにならないようにします。




5) 2013 年 2 月 16 日更新: 提案ボックスから入力されたタグの長さが入力ボックスの長さを超えた場合、次のタグの入力時に、入力ボックスは最初からタグを表示するか、最初のタグの位置に戻り、ここに示すように、カーソルが最後に置かれた場所からではありません - http://jqueryui.com/autocomplete/#multiple。これは修正されました。

これは、1 つの配列のみが使用され、提案は常に最長の提案の幅である同様のフィドルです - FIDDLE

質問に対する主な解決策を提供してくれた Jeffery To と、上記の mod の作成に役立つアイデアを提供してくれた Vadim と Dom に感謝します。

4

3 に答える 3

10

他の回答が示唆しているように、入力フィールドのテキストの幅を測定し (隠し要素を使用)、オートコンプリート ボックスをオフセットします。オートコンプリート ボックスの幅をリセットして、最長の提案 ( 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:別のオートコンプリート ボックスの位置修正

于 2013-02-08T02:45:43.973 に答える
2

JQuery の multiple demoを使用して、非表示のスパン要素を作成することができます

<span id="characterSpan" style="visibility: hidden;"></span>

それを使用して、入力のval().

そこから、使用.width()してスパンの幅を取得し、オートコンプリートのopen( event, ui )イベントを使用します。

open: function( event, ui ) {
        var span = $('#characterSpan');
        var width = span.width();
        width > $('#query').width() ? 
        width = parseInt($('#query').position().left + $('#query').width()) : 
        width = parseInt($('#query').position().left + width);

        $('.ui-autocomplete.ui-menu').css('left', width + 'px');
    }

デモ: http://jsfiddle.net/dirtyd77/5ySF9/8/

これについて十分に説明したいと思います。質問があればお知らせください。

于 2013-02-07T17:43:27.273 に答える
1

私はこの質問への答えに基づいて答えました。その回答で述べたように、IE<9はこれを機能させるためにいくつかの追加のコードが必要になります。

基本的に、入力要素の内容を書き出すスパンを作成します。次に、このスパンの幅を使用してオフセットを計算します。JqueryUIは、実際に値をオフセットできる位置フックを提供します。だからHTML

<input id="query" style="width: 300px" />
<span id="faux" style="display:none" />

そしてJS

    var query= $("#query");
    var faux = $("#faux");
    query.autocomplete({
        source: mySource
    }).on("keydown", function() {
        var off = query.selectionStart;
        faux.text(query.val().substring(0, off).replace(/\s/g, "\u00a0"));
        query.autocomplete("option", "position", 
              {my: "left top", at: "left+" + faux.outerWidth() + " bottom"});
    });

作業中のJSFiddle

于 2013-02-07T16:25:46.590 に答える