2013-05-17 7 views
16

私はSelect2(バージョン3.4.0)を使用してタグリストに値を設定しています。タグはajaxコールを介して既存のものと照合され、新しいタグの作成を可能にするためにcreateSearchChoiceを使用しています。コードは、これまでの作品、そしてこのようなものになります。ノートcreateSearchChoiceで追加(new)除き、SelectS2 with createSearchChoiceは、マッチ、バグ、または何かが欠けていても、キーボード入力用に新しく作成された選択肢を使用しますか?

$(mytags).select2({ 
    multiple: true, 
    placeholder: "Please enter tags", 
    tokenSeparators: [ "," ], 
    ajax: { 
     multiple: true, 
     url: myurl, 
     dataType: "json", 
     data: function(term, page) { 
      return { 
       q: term 
      }; 
     }, 
     results: function(data, page) { 
      return data; 
     } 
    }, 
    createSearchChoice: function(term) { 
     return { 
      id: term, 
      text: term + ' (new)' 
     }; 
    }, 
}); 

すべてのかなり標準を。私はこれが既存のタグではないことを知る必要があります。

「new-tag」と入力すると、リストの一番上に「new-tag(new)」というタグが表示され、選択すると「new-tag - タグ(新規) "、期待どおり。タグがすでに存在する場合、Select2は一致を検出し、「(新しい)」選択肢は作成されません。リターンを押すか、マッチをクリックすると、期待どおりに動作します。

この問題は、一致するものがあるときにコンマ(自分の単一のtokenSeparatorsエントリ)を入力すると表示されます。 Select2はそのトークンを閉じ、リストにタグを追加しますが、 "(新しい)"ラベルが付加されています。つまり、それがない場合でもcreateSeachChoiceの戻り値を使用します。

これはSelect2のバグですか、間違って使用していますか(代わりに何をする必要がありますか)?

答えて

16

これはバグかどうかわかりません - いずれにしても、現時点ではGitHubの問題追跡ツールでこの動作を参照している問題はありません。

ほとんどの場合、自分で動作を修正できます。考え方は、createSearchChoiceコールバックは、termが検索結果を参照するかどうかを判断できる必要があります。しかしcreateSearchChoiceは検索結果に直接アクセスできないため、どうすれば有効にできますか?さて、resultsコールバック内の検索結果の最新のバッチを保存してください。

var lastResults = []; 

$(...).select2({ 
    ajax: { 
     multiple: true, 
     url: "/echo/json/", 
     dataType: "json", 
     type: "POST", 
     data: function (term, page) { 
      return { 
       json: JSON.stringify({results: [{id: "foo", text:"foo"},{id:"bar", text:"bar"}]}), 
       q: term 
      }; 
     }, 
     results: function (data, page) { 
      lastResults = data.results; 
      return data; 
     } 
    }, 
    createSearchChoice: function (term) { 
     if(lastResults.some(function(r) { return r.text == term })) { 
      return { id: term, text: term }; 
     } 
     else { 
      return { id: term, text: term + " (new)" }; 
     } 
    } 
}); 

このコードはArray.someを使用していますので、あなたはそれを実行するために(SELECT2の最小要件です)IE8よりも良いものを必要とするが、もちろん、動作をエミュレートすることが可能です。

See it in action

ただし、現在の検索語句に対応する検索結果がすでに受信されている場合にのみ、このコードは正しくで動作します。

非常に速く入力し、既存のタグに対応する検索語句を作成しますが、そのタグを含む検索結果が到着する前にカンマでヒットした場合、createSearchChoiceは以前のタグの存在をテストします受信した検索結果。それらの結果がでない場合、タグを含む場合、タグは「新しい」として表示されます。

残念ながら、私はあなたがこれが起こるのを防ぐために何かできるとは考えていません。

+0

私のケースでは、結果は十分速くなければならず、ほとんどの場合は十分である限り、十分であるはずです。 –

+0

すばらしい答えJon。私はあなたのフィドルであなたが "バー"を入力し、あなたのキーボードで入力したら、 "foo"が選択され、希望の振る舞いではないと思うことに気がつきました。 – Marklar

+0

この回答が書かれているので、これについてGitHubに問題が追加されました:https://github.com/ivaynberg/select2/issues/794。私は作業中の提案の基本的な実装をしており、すぐにプル要求を提出する予定です(私は上記のリンクでコメントします)。 –

4

結果をtweekingするのではなく、サーバー側で作業する方がよいと思います。

サーバーは、タグが見つからない場合は、新しいタグとJSONの答えを返す

{"more":false,"results":[{"id":"whatever","text":"new-tag (new)"}]} 
2

を作る「createSearchChoice」の別のパラメータがあります - 「ページ」は、すべての選択肢を示しています、あなたはそれで簡単に虫を見つけることができます。

createSearchChoice = function (term, page) { 
    if(page.some(function(item) { 
     return item.text.toLowerCase() === term.toLowerCase(); 
    })){ 
     return { val: term, name: term + '*' }; 
    } 
} 
関連する問題