จะรับค่าที่เลือกทั้งหมดจาก <select multiple = multiple> ได้อย่างไร


116

ดูเหมือนแปลกฉันไม่พบสิ่งนี้ที่ถามไปแล้ว แต่นี่มันไปแล้ว!

ฉันมี html ดังนี้:

<select id="select-meal-type" multiple="multiple">
    <option value="1">Breakfast</option>
    <option value="2">Lunch</option>
    <option value="3">Dinner</option>
    <option value="4">Snacks</option>
    <option value="5">Dessert</option>
</select>

ฉันจะรับค่าทั้งหมด (อาร์เรย์) ที่ผู้ใช้เลือกในจาวาสคริปต์ได้อย่างไร

ตัวอย่างเช่นหากผู้ใช้เลือกอาหารกลางวันและของว่างฉันต้องการอาร์เรย์เป็น {2, 4}

ดูเหมือนว่ามันจะเป็นงานง่ายๆ แต่ดูเหมือนจะทำไม่ได้

ขอบคุณ.




คำตอบ:


105

วิธีปกติ:

var values = $('#select-meal-type').val();

จากเอกสาร :

ในกรณีของ<select multiple="multiple">องค์ประกอบ.val()เมธอดจะส่งคืนอาร์เรย์ที่มีตัวเลือกที่เลือกไว้


10
@augurone: ฉันอ้างว่าเป็น?
Felix Kling

9
@FelixKling คุณเพิ่งเข้าใจผิดใครบางคนที่อาจรวม jQuery lib ทั้งหมดไว้ในทันทีก่อนที่เขาจะรู้ว่าเขาไม่ควรเว้นแต่ว่าเขาต้องการจริงๆ
Aamir Afridi

32
@AamirAfridi: คำถามถูกแท็กด้วย jQuery การแท็กคำถามด้วยไลบรารีมักจะหมายความว่า op ใช้ไลบรารีนั้นและยินดีต้อนรับคำตอบที่ใช้ไลบรารี ฉันขอแนะนำทางเลือกอื่นในการเข้าสู่ jQuery ในวันนี้หรือไม่ อาจจะ. แต่คำถามนี้มากกว่า 3 ปี ดูความคิดเห็นของ OP ในคำตอบอื่น ๆ : stackoverflow.com/questions/11821261/…
Felix Kling

12
คุณพูดถูก มันสมเหตุสมผลแล้วถ้าคำถามถูกแท็กด้วย jQuery 😐
Aamir Afridi

148

เว้นแต่คำถามจะถาม JQuery คำถามควรได้รับคำตอบก่อนในจาวาสคริปต์มาตรฐานเนื่องจากหลาย ๆ คนไม่ได้ใช้ JQuery ในไซต์ของตน

จาก RobG วิธีรับค่าที่เลือกทั้งหมดของกล่องเลือกหลายรายการโดยใช้ JavaScript :

  function getSelectValues(select) {
  var result = [];
  var options = select && select.options;
  var opt;

  for (var i=0, iLen=options.length; i<iLen; i++) {
    opt = options[i];

    if (opt.selected) {
      result.push(opt.value || opt.text);
    }
  }
  return result;
}

24
มันติดแท็ก jquery
Kyle

1
ฮ่าไม่เห็นว่า: / ยัง +1
mw_21

6
เกี่ยวกับอะไรselectedOptions? ข้ามเบราว์เซอร์ไม่เพียงพอหรือไม่? Array.prototype.map.call(el.selectedOptions, function(x){ return x.value })
tenbits

โปรดทราบว่าเมื่อไม่มีvalueแอตทริบิวต์แล้ว=opt.value opt.text
ถึง

1
ในที่สุด! วานิลลา ... รสโปรดของฉัน
papiro

46

อันที่จริงฉันพบวิธีที่ดีที่สุดสั้นที่สุดเร็วที่สุดและเข้ากันได้มากที่สุดโดยใช้ JavaScript บริสุทธิ์ (สมมติว่าคุณไม่จำเป็นต้องรองรับ IE lte 8 อย่างสมบูรณ์) มีดังต่อไปนี้:

var values = Array.prototype.slice.call(document.querySelectorAll('#select-meal-type option:checked'),0).map(function(v,i,a) { 
    return v.value; 
});

อัพเดท (2017-02-14):

วิธีที่รวบรัดยิ่งขึ้นโดยใช้ ES6 / ES2015 (สำหรับเบราว์เซอร์ที่รองรับ):

const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);

7
หรือถ้าคุณมีองค์ประกอบ:Array.from(element.querySelectorAll("option:checked"),e=>e.value);
Someguynamedpie

1
เพียงแค่ FYI การใช้คอลเลคชัน selectedOptions / options จะเร็วกว่าการใช้ querySelectorAll
Adam Leggett

4
ขอบคุณ @AdamLeggett สำหรับการอ้างอิงให้กับผู้ที่ไม่ทราบว่าจะเปลี่ยนยี่ห้อ @ รหัส Someguynamedpie Array.from(element.selectedOptions).map(v=>v.value);เหนือไปที่:
KyleFarris

มันจะ แต่ดูคำตอบของฉันด้านล่าง - มันใช้ไม่ได้เลยบน IE และมีพฤติกรรมแปลก ๆ ใน Chrome และ Firefox เวอร์ชันเก่าบางรุ่น หากคุณไม่สนใจเกี่ยวกับประสิทธิภาพ querySelectorAll หรือ filtering element.options จะทำให้งานสำเร็จ นอกจากนี้คุณสามารถทำ [] .map.call () แทนการใช้ Array.from () ฉันไม่รู้ว่าสิ่งนี้จะส่งผลกระทบต่อประสิทธิภาพการทำงานอย่างไร แต่แน่นอนว่าจะไม่เป็นลบ
Adam Leggett

ใช้checked สิ่งนี้ใช้ได้กับฉันในเมนูแบบเลื่อนลงแบบเลือกได้หลายรายการ แต่ควรใช้ได้กับเมนูแบบเลื่อนลงทั้งหมดเช่นกัน$(".multiple_select > option:checked").each(function(){ console.log(this.value) });
Joviano Dias

15

หากคุณต้องการไปทางที่ทันสมัยคุณสามารถทำได้:

const selectedOpts = [...field.options].filter((x) => x.selected);

ตัว...ดำเนินการแมปซ้ำได้ ( HTMLOptionsCollection) กับอาร์เรย์

หากคุณสนใจเพียงแค่ค่าคุณสามารถเพิ่มการmap()โทร:

const selectedValues = [...field.options]
                     .filter((x) => x.selected)
                     .map((x)=>x.value);

คำตอบนี้สมควรได้รับเครดิตมากขึ้น โซลูชั่นที่สมบูรณ์แบบขอบคุณ!
Silver Ringvee

10

ขั้นแรกให้ใช้Array.fromเพื่อแปลงHTMLCollectionวัตถุเป็นอาร์เรย์

let selectElement = document.getElementById('categorySelect')
let selectedValues = Array.from(selectElement.selectedOptions)
        .map(option => option.value) // make sure you know what '.map' does

// you could also do: selectElement.options


6

อัปเดตตุลาคม 2019

สิ่งต่อไปนี้ควรทำงานแบบ "สแตนด์อะโลน" บนเบราว์เซอร์สมัยใหม่ทั้งหมดโดยไม่มีการอ้างอิงหรือการถ่ายโอนข้อมูลใด ๆ

<!-- display a pop-up with the selected values from the <select> element -->

<script>
 const showSelectedOptions = options => alert(
   [...options].filter(o => o.selected).map(o => o.value)
 )
</script>

<select multiple onchange="showSelectedOptions(this.options)">
  <option value='1'>one</option>
  <option value='2'>two</option>
  <option value='3'>three</option>
  <option value='4'>four</option>
</select>

4

ลองสิ่งนี้:

$('#select-meal-type').change(function(){
    var arr = $(this).val()
});

การสาธิต

$('#select-meal-type').change(function(){
  var arr = $(this).val();
  console.log(arr)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select-meal-type" multiple="multiple">
  <option value="1">Breakfast</option>
  <option value="2">Lunch</option>
  <option value="3">Dinner</option>
  <option value="4">Snacks</option>
  <option value="5">Dessert</option>
</select>

ซอ


3

หากคุณต้องการตามที่คุณแสดงด้วยตัวแบ่งหลังจากแต่ละค่า

$('#select-meal-type').change(function(){
    var meals = $(this).val();
    var selectedmeals = meals.join(", "); // there is a break after comma

    alert (selectedmeals); // just for testing what will be printed
})

2

หากคุณต้องการตอบสนองต่อการเปลี่ยนแปลงคุณสามารถลองสิ่งนี้:

document.getElementById('select-meal-type').addEventListener('change', function(e) {
    let values = [].slice.call(e.target.selectedOptions).map(a => a.value));
})

[].slice.call(e.target.selectedOptions)เป็นสิ่งจำเป็นเพราะe.target.selectedOptionsผลตอบแทนที่ไม่HTMLCollection Arrayการเรียกนั้นจะแปลงเป็นเพื่อArrayให้เราสามารถใช้mapฟังก์ชันซึ่งดึงค่าออกมาได้


1
น่าเสียดายที่สิ่งนี้ใช้ไม่ได้ทุกที่ปรากฎว่า IE11 ไม่มีฟิลด์ที่เลือกตัวเลือก สิ่งต่อไปนี้ใช้ได้ผล:Array.prototype.slice.call(field.querySelectorAll(':checked'))
JamesDev

0

สิ่งต่อไปนี้จะเป็นทางเลือกของฉัน:

let selectElement = document.getElementById('categorySelect');
let selectedOptions = selectedElement.selectedOptions || [].filter.call(selectedElement.options, option => option.selected);
let selectedValues = [].map.call(selectedOptions, option => option.value);

มันสั้นมันเร็วบนเบราว์เซอร์สมัยใหม่และเราไม่สนใจว่ามันจะเร็วหรือไม่ในเบราว์เซอร์ที่มีส่วนแบ่งตลาด 1%

หมายเหตุ selectedOptions มีพฤติกรรมที่แปลกประหลาดในเบราว์เซอร์บางตัวเมื่อประมาณ 5 ปีที่แล้วดังนั้นการดมกลิ่นของตัวแทนผู้ใช้จึงไม่อยู่ในบรรทัดที่นี่


0

คุณสามารถใช้ได้ selectedOptions

var selectedValues = Array.from(document.getElementById('select-meal-type').selectedOptions).map(el=>el.value);
console.log(selectedValues);
<select id="select-meal-type" multiple="multiple">
    <option value="1">Breakfast</option>
    <option value="2" selected>Lunch</option>
    <option value="3">Dinner</option>
    <option value="4" selected>Snacks</option>
    <option value="5">Dessert</option>
</select>


-1

ทำงานได้ทุกที่โดยไม่ต้องใช้ jquery:

var getSelectValues = function (select) {
    var ret = [];

    // fast but not universally supported
    if (select.selectedOptions != undefined) {
        for (var i=0; i < select.selectedOptions.length; i++) {
            ret.push(select.selectedOptions[i].value);
        }

    // compatible, but can be painfully slow
    } else {
        for (var i=0; i < select.options.length; i++) {
            if (select.options[i].selected) {
                ret.push(select.options[i].value);
            }
        }
    }
    return ret;
};

selectedOptiongsไม่รองรับใน IE
Dustin Poissant
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.