Select2 dropdown แต่อนุญาตค่าใหม่ตามผู้ใช้?


125

ฉันต้องการให้รายการแบบเลื่อนลงพร้อมชุดของค่า แต่ยังอนุญาตให้ผู้ใช้ "เลือก" ค่าใหม่ที่ไม่มีอยู่ในรายการนั้น

ฉันเห็นว่าselect2รองรับสิ่งนี้หากคุณใช้งานในtagsโหมด แต่มีวิธีทำได้โดยไม่ต้องใช้แท็กหรือไม่?


1
Select2 ไม่เคยได้ผลสำหรับฉันอย่างน้อย createSearchChoice ไม่เคยทำงานให้ฉันใน 4.0.3 และฉันไม่ต้องการให้ผู้ใช้ของฉันรอ 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
ขออภัยสำหรับการตอบกลับล่าช้า แต่ขอบคุณมากสำหรับการแก้ปัญหาของคุณ! ผู้โพสต์อีกคนโพสต์ลิงก์ไปยังส่วนสำคัญของคุณซึ่งทำให้คุณน่ากลัวเป็นทวีคูณ! :)
johnjohn

rrauenza สุดยอดสิ่งที่ฉันกำลังมองหา
Matthias S

4
การเพิ่มselectOnBlur: trueพินัยกรรมโปรดดู: stackoverflow.com/questions/25616520/…
Alireza Fattahi

1
เพียงแค่หัวขึ้นสำหรับผู้อ่านในอนาคตคุณอาจต้องการที่จะใช้พร้อมกับtags: [] createSearchChoice
Kevin Brown

5
เสียงซอที่เชื่อมโยงด้านบนดูเหมือนจะหัก
Wolfr

175

คำตอบที่ดีให้โดย@fmpwizardงานสำหรับ Select2 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เหตุการณ์ได้ง่ายคุณสมบัติพิเศษยังช่วยให้คุณสามารถแสดงผลตัวเลือกที่แตกต่างกันเล็กน้อยในผลลัพธ์ ดังนั้นหากคุณต้องการแสดงให้เห็นถึงความจริงที่ว่าเป็นตัวเลือกใหม่โดยใส่ " (ใหม่) " ไว้ข้างๆคุณสามารถทำสิ่งนี้ได้

$("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

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 บราวน์
เอ็ม Salah

นี่ควรเป็นคำตอบอันดับต้น ๆ ฉันค้นหาสิ่งนี้มาระยะหนึ่งแล้วและตัวเลือกนี้ตอบทุกคำถามที่ฉันเห็นในหัวข้อนี้
Justin

14

เพียงเพื่อประโยชน์ของเก็บรหัสชีวิตผมโพสต์@rrauenza รหัสซอลจากความคิดเห็นของเขา

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 คุณสามารถยืนยัน?
IcedDante

@IcedDante รหัสกำลังทำงาน ประเด็นในซอเป็นเพียงการแสดงให้เห็นว่าควรทำอย่างไร (สิ่งที่เลือกซ่อนอยู่ในซอ)
Michel Ayres

4
เมื่อฉันไปที่ซอฉันไม่เห็นดรอปดาวน์ select2 ที่ใดเลย จะดีไหมถ้ามีตัวอย่างว่า ... ทำอะไรได้จริง?
IcedDante

ฉันจะตั้งค่าข้อมูลจากแหล่งภายนอกได้อย่างไร? ฉันหมายความว่าอย่างไรถ้าฉันต้องการโหลดเมืองของประเทศที่เลือกและประเทศที่เลือกนั้นเป็นแบบเลื่อนลง?
Ali Baig

12

เนื่องจากคำตอบเหล่านี้จำนวนมากใช้ไม่ได้ใน 4.0+ หากคุณใช้ ajax คุณสามารถให้เซิร์ฟเวอร์เพิ่มค่าใหม่เป็นตัวเลือกได้ ดังนั้นมันจะได้ผลดังนี้:

  1. ผู้ใช้ค้นหาค่า (ซึ่งส่งคำขอ ajax ไปยังเซิร์ฟเวอร์)
  2. หากพบว่าค่าดีมากให้คืนค่าตัวเลือก หากไม่เพียงแค่ให้เซิร์ฟเวอร์ต่อท้ายตัวเลือกเช่นนี้:[{"text":" my NEW option)","id":"0"}]
  3. เมื่อส่งแบบฟอร์มให้ตรวจสอบเพื่อดูว่าตัวเลือกนั้นอยู่ในฐานข้อมูลหรือไม่และหากไม่ได้สร้างขึ้นก่อนบันทึก


4

Improvent ในคำตอบ @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

ฉันใช้สิ่งนี้โดยมีการปรับเปลี่ยนเล็กน้อยฉันจะตอบกลับในไม่กี่วินาที แต่ขอบคุณ
สาม


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

ในกรณีส่วนใหญ่เราจำเป็นต้องเปรียบเทียบค่ากับการลงทะเบียนที่ไม่ละเอียดอ่อน และรหัสนี้จะส่งกลับเท็จซึ่งจะนำไปสู่การสร้างระเบียนที่ซ้ำกันในฐานข้อมูล ยิ่งไปกว่านั้น 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.