Select2ドロップダウンですが、ユーザーによる新しい値を許可しますか?


125

値のセットを含むドロップダウンを用意し、そこにリストされていない新しい値をユーザーが「選択」できるようにしたいのですが。

モードで使用している場合、select2がこれをサポートしているようですがtags、タグを使用せずにそれを行う方法はありますか?


1
Select2が私のために機能しなかった、少なくとも4.0.3でcreateSearchChoiceが私のために機能しなかった、そして同じキーワードを返すためにユーザーがajaxが完了するのを待たせたくなかったので、自分のライブラリをロールアウトする必要がありました。私と同じようにまだ混乱している他の人を助けるかもしれないので、それを共有します。私の答えに同意しない場合は、反対票を投じないでください:github.com/razzbee/tagcomplete
razzbee

回答:


100

バージョン4+については、以下のKevin Brownによる回答を確認してください

Select2 3.5.2以前では、次のようなものを使用できます。

$(selector).select2({
  minimumInputLength:1,
  "ajax": {
    data:function (term, page) {
      return { term:term, page:page };
    },
    dataType:"json",
    quietMillis:100,
    results: function (data, page) {
      return {results: data.results};
    },
    "url": url
  },
  id: function(object) {
    return object.text;
  },
  //Allow manually entered text in drop down.
  createSearchChoice:function(term, data) {
    if ( $(data).filter( function() {
      return this.text.localeCompare(term)===0;
    }).length===0) {
      return {id:term, text:term};
    }
  },
});

(select2メーリングリストの回答から取得されましたが、現在リンクを見つけることができません)


4
返信が遅れて申し訳ありませんが、解決策をありがとうございました!もう1つのポスターには、要点へのリンクが掲載されています。:)
johnjohn 2013

rrauenza素晴らしかった、まさに私が探していたもの
Matthias S

4
追加selectOnBlur: true仕事をすることは参照してください。stackoverflow.com/questions/25616520/...
アリレザFattahi

1
将来の読者に向けた準備として、おそらくとtags: []一緒に使用したいと思うでしょうcreateSearchChoice
Kevin Brown

5
上記のフィドルは壊れているようです。
Wolfr

175

優秀な答えが提供する@fmpwizardは Selectセレクト3.5.2および以下のために働く、それは4.0.0で動作しません

非常に早い段階から(おそらくこの質問ほど早くはないかもしれませんが)、Select2は「タグ付け」をサポートしています。これはtagsオプションで有効にでき、ドキュメントの例を試すことができます

$("select").select2({
  tags: true
});

デフォルトでは、これにより、ユーザーが入力した検索語と同じテキストを持つオプションが作成されます。特別な方法でマークを付ける場合は、使用するオブジェクトを変更するか、選択したオブジェクトをリモートで作成できます。

$("select").select2({
  tags: true,
  createTag: function (params) {
    return {
      id: params.term,
      text: params.term,
      newOption: true
    }
  }
});

select2:selectイベントを通じて渡されたオブジェクトのスポットフラグとして機能することに加えて、追加のプロパティを使用すると、結果のオプションをわずかに異なる方法でレンダリングできます。したがって、「(new)」を横に付けることで、それが新しいオプションであることを視覚的に伝えたい場合は、次のようにすることができます。

$("select").select2({
  tags: true,
  createTag: function (params) {
    return {
      id: params.term,
      text: params.term,
      newOption: true
    }
  },
  templateResult: function (data) {
    var $result = $("<span></span>");

    $result.text(data.text);

    if (data.newOption) {
      $result.append(" <em>(new)</em>");
    }

    return $result;
  }
});

@ Markus1980Wien
abiieez

私はこのスニペットを複数回使用したと思います。
Sahu V Kumar

ダブルチェックが機能しない場合は、select2にこのオプションを追加し、ajaxオプションに追加しないでください。select2 ajaxの場合
Zohaib 2017

2
この方法でバージョンselect2(4.0.6)で機能します:$( "select")。select2({tags:true、createTag:function(params){return {id:params.term、text:params.term、newOption :true}}、templateResult:function(data){var result = data.text; if(data.newOption){result = result + '(new)';} return result;}}); ありがとう@Kevin Brown
M. Salah

これがトップレスポンスになるはずです。私はこれについてしばらく探していましたが、このオプションは、トピックで見たすべての質問に答えます。
ジャスティン

14

コードを存続させるために、コメントから@rrauenza Fiddleのコード投稿しています。

HTML

<input type='hidden' id='tags' style='width:300px'/>

jQuery

$("#tags").select2({
    createSearchChoice:function(term, data) { 
        if ($(data).filter(function() { 
            return this.text.localeCompare(term)===0; 
        }).length===0) 
        {return {id:term, text:term};} 
    },
    multiple: false,
    data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});

2
フィドルに行ったのですが、Chromeではうまくいかないようです。確認できますか?
IcedD​​ante 2015

@IcedD​​anteコードが機能しています。フィドルのポイントは、それがどのように行われるべきかを示すことです(選択はフィドルに隠されています)
Michel Ayres

4
フィドルに移動すると、select2ドロップダウンがどこにも表示されません。実際に何かをする例があればいいのではないでしょうか。
IcedD​​ante 2015

外部ソースからデータを設定するにはどうすればよいですか?私が選択した国の都市をロードしたいのですが、選択した国自体がドロップダウンである場合はどうなりますか?
Ali Baig

12

これらの回答の多くは4.0以降では機能しないため、ajaxを使用している場合は、サーバーに新しい値をオプションとして追加させることができます。したがって、次のように機能します。

  1. ユーザーが値を検索する(サーバーへのajax要求を行う)
  2. 値が優れている場合は、オプションを返します。そうでない場合は、サーバーに次のようにそのオプションを追加してもらいます。[{"text":" my NEW option)","id":"0"}]
  3. フォームが送信されたら、そのオプションがデータベースにあるかどうかを確認し、ない場合は作成する前に保存してください。


4

@fmpwizardの回答の改善:

//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
  if ( $(data).filter( function() {
    return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
  }).length===0) {
    return {id:term, text:term};
  }
},

//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined

私はこれを少し修正して使用しましたが、すぐに答えを上げますが、感謝します。
Sam


1
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;

ほとんどの場合、値を区別されないレジスタと比較する必要があります。そして、このコードはfalseを返し、データベースに重複したレコードが作成されます。さらに、String.prototype.localeCompare()はブラウザーSafaryでサポートされておらず、このコードはこのブラウザーでは機能しません。

return this.text.localeCompare(term)===0;

に置き換えてください

return this.text.toLowerCase() === term.toLowerCase();

1

助けてくれてありがとう、私は以下のコードをCodeigniter II内で使用しました。バージョン3.5.2のselect2を使用しています。

var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
    ajax: {
        url: location_url,
        dataType: 'json',
        quietMillis: 100,
        data: function (term) {
            return {
                term: term
            };
        },
        results: function (data) {
            results = [];
            $.each(data, function(index, item){
                results.push({
                    id: item.location_id,
                    text: item.location_name
                });
            });
            return {
                results: results
            };
        }
    },
    //Allow manually entered text in drop down.
    createSearchChoice:function(term, results) {
        if ($(results).filter( function() {
            return term.localeCompare(this.text)===0; 
        }).length===0) {
            return {id:term, text:term + ' [New]'};
        }
    },
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.