Select2 dropdown tapi izinkan nilai baru oleh pengguna?

125

Saya ingin memiliki dropdown dengan sekumpulan nilai tetapi juga memungkinkan pengguna untuk "memilih" nilai baru yang tidak terdaftar di sana.

Saya melihat bahwa select2 mendukung ini jika Anda menggunakannya dalam tagsmode, tetapi adakah cara untuk melakukannya tanpa menggunakan tag?

johnjohn
sumber
1
Select2 tidak pernah berhasil untuk saya, setidaknya createSearchChoice tidak pernah berfungsi untuk saya di 4.0.3, dan saya tidak ingin pengguna saya menunggu ajax selesai untuk mengembalikan kata kunci yang sama, jadi saya harus meluncurkan perpustakaan saya sendiri, saya hanya membagikannya karena saya pikir ini dapat membantu orang lain yang masih bingung seperti saya, tolong jangan turunkan suara jika Anda tidak setuju dengan jawaban saya: github.com/razzbee/tagcomplete
razzbee

Jawaban:

100

Untuk versi 4+, periksa jawaban di bawah ini oleh Kevin Brown

Di Select2 3.5.2 dan yang lebih lama, Anda dapat menggunakan sesuatu seperti:

$(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};
    }
  },
});

(diambil dari jawaban di milis select2, tetapi tidak dapat menemukan tautannya sekarang)

fmpwizard
sumber
4
Maaf atas tanggapan yang terlambat tetapi terima kasih banyak atas solusinya! Poster lainnya, memposting tautan ke inti Anda btw yang membuat Anda luar biasa dua kali lipat! :)
johnjohn
rrauenza mengagumkan, persis apa yang saya cari
Matthias S
4
Menambahkan surat selectOnBlur: truewasiat, silakan lihat: stackoverflow.com/questions/25616520/…
Alireza Fattahi
1
Sekadar informasi untuk pembaca masa depan, Anda mungkin ingin menggunakannya tags: []bersama createSearchChoice.
Kevin Brown
5
Biola yang ditautkan di atas sepertinya rusak.
Wolfr
175

The jawaban yang sangat baik yang disediakan oleh @fmpwizard bekerja untuk Select2 3.5.2 dan bawah, tapi itu tidak akan berhasil di 4.0.0 .

Sejak awal (tapi mungkin tidak sedini pertanyaan ini), Select2 telah mendukung "pemberian tag": di mana pengguna dapat menambahkan nilai mereka sendiri jika Anda mengizinkannya. Ini dapat diaktifkan melalui tagsopsi, dan Anda dapat bermain-main dengan contoh di dokumentasi .

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

Secara default, ini akan membuat opsi yang memiliki teks yang sama dengan istilah pencarian yang mereka masukkan. Anda dapat memodifikasi objek yang digunakan jika Anda ingin menandainya dengan cara khusus, atau membuat objek dari jarak jauh setelah dipilih.

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

Selain berfungsi sebagai tanda yang mudah dikenali pada objek yang diteruskan melalui select2:selectacara, properti tambahan juga memungkinkan Anda merender opsi sedikit berbeda pada hasilnya. Jadi, jika Anda ingin memberi sinyal visual bahwa ini adalah opsi baru dengan meletakkan " (baru) " di sebelahnya, Anda dapat melakukan sesuatu seperti ini.

$("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;
  }
});
Kevin Brown
sumber
Itu sangat membantu @ Markus1980Wien
abiieez
Saya rasa saya telah menggunakan potongan ini beberapa kali.
Sahu V Kumar
Jika tidak berfungsi, periksa dua kali Anda telah menambahkan opsi ini pada select2 tidak menambahkan opsi ajax. untuk select2 ajax
Zohaib
2
Cara kerjanya di versi select2 (4.0.6) dengan cara ini: $ ("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;}}); terima kasih @Kevin Brown
M. Salah
Ini harus menjadi respons teratas. Saya telah mencari beberapa saat untuk ini, dan opsi ini menjawab setiap pertanyaan yang saya lihat tentang topik tersebut.
Justin
14

Demi menjaga kodenya tetap hidup, saya memposting kode @rrauenza Fiddle dari komentarnya .

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'}]
});
Michel Ayres
sumber
2
Saya mempelajari biola, tetapi tampaknya tidak berhasil untuk saya di Chrome. Bisakah kamu mengkonfirmasi?
IcedDante
@IcedDante kode bekerja. intinya dalam biola hanya untuk menunjukkan bagaimana hal itu harus dilakukan (pilihan tersembunyi di dalam biola)
Michel Ayres
4
Ketika saya pergi ke biola, saya tidak melihat dropdown select2 di mana pun. Bukankah menyenangkan memiliki contoh yang benar-benar ... melakukan sesuatu?
IcedDante
Bagaimana cara mengatur data dari sumber eksternal? Maksud saya bagaimana jika saya ingin memuat kota dari negara tertentu dan negara yang dipilih itu sendiri adalah dropodown?
Ali Baig
12

Karena banyak dari jawaban ini tidak berfungsi di 4.0+, jika Anda menggunakan ajax, Anda dapat meminta server menambahkan nilai baru sebagai opsi. Jadi akan bekerja seperti ini:

  1. Pengguna mencari nilai (yang membuat permintaan ajax ke server)
  2. Jika nilainya ternyata bagus, kembalikan opsi. Jika tidak, server menambahkan opsi itu seperti ini:[{"text":" my NEW option)","id":"0"}]
  3. Ketika formulir dikirimkan, periksa untuk melihat apakah opsi itu ada di db dan jika tidak buat sebelum menyimpannya.
Eric
sumber
4

Meningkatkan jawaban @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
Vikash Singh
sumber
Saya menggunakan ini dengan sedikit modifikasi, saya akan memberikan jawaban saya sebentar lagi tapi terima kasih.
Sam
1
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;

Dalam banyak kasus, kita perlu membandingkan nilai dengan register tidak sensitif. Dan kode ini akan mengembalikan false, yang akan mengarah pada pembuatan rekaman duplikat dalam database. Selain itu, String.prototype.localeCompare () tidak didukung oleh Safary browser dan kode ini tidak akan berfungsi di browser ini;

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

akan lebih baik menggantikan

return this.text.toLowerCase() === term.toLowerCase();
mengalahkan
sumber
1

Terima kasih atas bantuannya, saya menggunakan kode di bawah ini dalam Codeigniter II saya menggunakan versi: 3.5.2 dari 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]'};
        }
    },
});
Sam
sumber