4

特定のアイテムがデフォルトでフォーカスされるように jQuery オートコンプリートを拡張するのに苦労しています。すぐに使える機能はかなりうまく機能しますが、完全ではありません。オプションを使用するautoFocusと、最初の項目に自動的にフォーカスできます。

$( "#input" ).autocomplete({
    source: "autocomplete.php",
    minLength: 1,
    autoFocus: true
});

ただし、どのアイテムがフォーカスされているかをもっと制御したいと思います。ユーザーが「eng」と入力し、ソースが返す関連項目が次の場合:

  • アメリカ英語
  • イギリス英語
  • 英語
  • スコットランド英語

3 番目の項目であるEnglishをデフォルトでフォーカスしたいと思います (つまり、他の結果を表示したいのに、実際にはユーザーの入力で始まる項目です)。理想的には、私のソース - autocomplete.php - は、どのアイテムがデフォルトのフォーカスになるかを示すことができます。

何か案は?どうやって始めればいいのかさえわかりません。

4

2 に答える 2

4

openイベントを利用して、これを実現する簡単な方法があります。クライアント側のコードでデフォルト項目の選択を処理するか、選択したい項目とともに追加のプロパティを送信できます。両方のオプションについて説明します。

クライアントで選択された用語で始まる提案の焦点:

$("input").autocomplete({
    source: /* ... */,
    open: function (event, ui) {
        var menu = $(this).data("uiAutocomplete").menu
            , i = 0
            , $items = $('li', menu.element)
            , item
            , text
            , startsWith = new RegExp("^" + this.value, "i");

        for (; i < $items.length && !item; i++) {
            text = $items.eq(i).text();
            if (startsWith.test(text)) {
                item = $items.eq(i);
            }
        }

        if (item) {
            menu.focus(null, item);
        }
    }
});

基本的には、オートコンプリートのメニューが開いているときに次のことを行うという考え方です。

  • 検索語で始まる単語を探すための正規表現を作成します。
  • 各メニュー項目を反復処理し、正規表現に対してそのテキストをテストします。一致が見つかったら、反復を停止して値を保存します。
  • 値を取得した場合は、focusメニューのメソッドを使用してアイテムを強調表示します。

例: http://jsfiddle.net/J5rVP/40/ ( English またはS cots Englishを検索してみてください)

このコードはローカル データ ソースを使用していますが、リモート ソースでも同様に機能するはずです。


サーバー上で選択された用語で始まる提案のフォーカス

上記の例を拡張して、データを送信する方法を微調整して、検索ごとにサーバー側のコードが選択するアイテムを決定するようにすることができます。これは、選択したいアイテムに追加のプロパティを指定するだけで実行できます。たとえば、JSON 応答は次のようになります。

[{"label":"American English","select":true},{"label":"British English"},{"label":"English"},{"label":"Scots English"}]

select「アメリカ英語」のプロパティに注意してください。これは、デフォルトでそのアイテムを選択することをオートコンプリートに示します。

次に、ウィジェットの初期化コードを更新して、open上記のようにイベントを利用します。今回は、次のselectプロパティを持つアイテムを検索しているだけです。

$("input").autocomplete({
    source: "autocomplete.php",
    open: function (event, ui) {
        var menu = $(this).data("uiAutocomplete").menu,
            i = 0,
            $items = $('li', menu.element),
            item,
            data;

        for (; i < $items.length && !item; i++) {
            data = $items.eq(i).data("ui-autocomplete-item");
            if (data.select) {
                item = $items.eq(i);
            }
        }

        if (item) {
            menu.focus(null, item);
        }
    }
});

例: http://jsfiddle.net/J5rVP/42/

上記の例では、アメリカ英語が常に選択されていることに注意してください。オートコンプリートはユーザーが入力するたびに新しいリクエストを発行するため、サーバーはさまざまな候補データで応答し、したがって別のアイテムが選択されます。

selectまた、私は PHP を知らないので、プロパティを JSON に追加する方法について話すことはできません。しかし、それは非常に単純で、正規表現を使用する最初の例の JavaScript コードのように見えるかもしれません。

于 2013-01-29T02:52:00.023 に答える
2

検索語で始まる単語など、優先度の高いアイテムが最初に表示されるように、マッピング データを別の方法で見ることをお勧めします。

その後、AutoComplete/categories のデモに従って、結果を分離できます。これは、変更するコードを作成しようとするよりもはるかに簡単autoFocusです。より高いランクがトップになり、そこからフォーカスが開始されます。

http://jqueryui.com/autocomplete/#categories

結果をランク付けするために使用できる概念は次のとおりです。

function rankResult($str, $term){
     /* 0 is first letters, 1 is in first word, 2 is starts another word, 3 is in word not first word*/
     $words=explode(' ', $str); 
     if(stripos($words[0],$term) !==false){
        return stripos($words[0],$term)==0 ? 0 : 1;
     }else{
        $rank=3;
        for( $i=1; $i< count( $words); $i++){
            if(stripos($words[$i],$term)===0){
                $rank=2;
            }
        }
        return $rank;
     }      
}

 $rank = rankResult('English', 'eng'); /*=> 0 */

ループオーバー:

  array('American English','British English','English','Scots English','HasEngInIt');

戻ってきた:

Array
(
    [0] => Array
        (
            [label] => American English
            [rank] => 2
        )

    [1] => Array
        (
            [label] => British English
            [rank] => 2
        )

    [2] => Array
        (
            [label] => English
            [rank] => 0
        )

    [3] => Array
        (
            [label] => Scots English
            [rank] => 2
        )

    [4] => Array
        (
            [label] => HasEngInIt
            [rank] => 1
        )

)

オートコンプリートに送信される前に、データがランクごとにグループ化されるように、少し並べ替えを行う必要があります

于 2013-01-29T02:41:12.793 に答える