Каков наилучший способ добавить параметры для выбора в качестве объекта JavaScript с помощью jQuery?


1380

Каков наилучший способ добавления параметров в <select>объект JavaScript с использованием jQuery?

Я ищу что-то, что мне не нужен плагин, но я также был бы заинтересован в плагинах, которые там есть.

Вот что я сделал:

selectValues = { "1": "test 1", "2": "test 2" };

for (key in selectValues) {
  if (typeof (selectValues[key] == 'string') {
    $('#mySelect').append('<option value="' + key + '">' + selectValues[key] + '</option>');
  }
}

Чистое / простое решение:

Это упрощенная версия matdumsa's :

$.each(selectValues, function(key, value) {
     $('#mySelect')
          .append($('<option>', { value : key })
          .text(value));
});

Изменения в matdumsa: (1) убрал тег закрытия для опции внутри append () и (2) переместил свойства / атрибуты на карту как второй параметр append ().


4
Может быть, помочь: texotela.co.uk/code/jquery/select (это была помощь для меня после того, как я наткнулся на этот вопрос)
— ManBugra

2
Перечисленная выше очищенная версия работает только в Jquery 1.4+. Для более старых версий используйте ответ в ответе
— Матдумсы

{value: key} должно быть {"value": key}, как видно из ответа matdumsa.
— Ник П

Я не верю в это, поскольку valueэто строка (и жестко закодированная), которую не нужно заключать в кавычки.
— Дэррил Хейн

1
Вместо этого заголовок должен звучать так: «Каков наилучший способ добавить опции для выбора из объекта JSON с помощью jQuery?»
— доктор Фред,

Ответы:


1384

Так же, как и другие ответы, в стиле jQuery:

$.each(selectValues, function(key, value) {   
     $('#mySelect')
         .append($("<option></option>")
                    .attr("value", key)
                    .text(value)); 
});

99
Прежде всего, я бы назначил $("#mySelect")переменную, иначе вызовы $("#mySelect")каждый раз внутри цикла очень расточительны, как и обновление DOM. См. Пункты № 3 и № 6 на artzstudio.com/2009/04/jquery-performance-rules/…
— Патрик,

7
ну, вы могли бы просто сделать var mySelect = $("#mySelect") outside of the каждый цикл. Это было бы намного эффективнее. Смотрите ответ Карла ниже
— Патрик

17
Моя рекомендация по улучшению стиля jQuery: $ ('# mySelect') .append ($ ("<option />") .val (key) .text (value));
— FAjir

10
С популярностью этого ответа стоит упомянуть, что вы должны избегать обновлений DOM в циклах. jsperf.com/jquery-append-array-vs-string
— jthomas

6
этот ответ был настолько вводящим в заблуждение из-за неправильного намерения ... attrи textна самом деле это методы $('<option/>')-объекта
— phil294

268
var output = [];

$.each(selectValues, function(key, value)
{
  output.push('<option value="'+ key +'">'+ value +'</option>');
});

$('#mySelect').html(output.join(''));

Таким образом, вы «касаетесь DOM» только один раз.

Я не уверен, может ли последняя строка быть преобразована в $ ('# mySelect'). Html (output.join ('')), потому что я не знаю внутренних компонентов jQuery (возможно, он выполняет некоторый анализ в html () метод)


20
Вы, очевидно, метод быстрее, чем «правильный» ответ выше, так как он также использует меньше jQuery.
— Teej

4
строка "$ ('# mySelect'). get (0) .innerHTML = output.join ('');" работает в Chrome и FF3.x, но не в IE7, насколько я могу судить
— blu

19
Это ломается, если keyесть некоторые кавычки или >, <в нем.
— Ник

3
И, если у меня есть два варианта, которые я не хочу потерять. Как я могу добавить эти новые значения параметров к существующим?
— VansFannel

6
Одним небольшим улучшением является объединение с использованием соединения, а не знака плюс, например: output.push ('<option value = "', key, '">', value, '</ option>');
— ММ.

202

Это немного быстрее и чище.

var selectValues = {
  "1": "test 1",
  "2": "test 2"
};
var $mySelect = $('#mySelect');
//
$.each(selectValues, function(key, value) {
  var $option = $("<option/>", {
    value: key,
    text: value
  });
  $mySelect.append($option);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="mySelect"></select>


3
Отлично. Чтобы добавить его, можно добавить дополнительные атрибуты для выбора. $ .each (selectValues, function (id, value, text) {$ ('# mySelect'). append ($ ("<option />", {id: id value: value, text: text}));} );
— ИДОК

45
Он считает, что лучше будет кэшировать `$ ('# mySelect')`, чтобы вы просматривали только один раз перед циклом. В настоящее время он ищет в DOM элемент для каждой опции.
— Сушант -

@ Sushanth-- насколько велика производительность, если набор маленький?
— ckarbass

3
@ckarbass - зависит, насколько велика ваша DOM. Потенциально большие и очень небольшие усилия, чтобы присвоить его переменной, значительно меньше, чем написать комментарий в SO!
— Ник H247

97

JQuery

var list = $("#selectList");
$.each(items, function(index, item) {
  list.append(new Option(item.text, item.value));
});

Ванильный JavaScript

var list = document.getElementById("selectList");
for(var i in items) {
  list.add(new Option(items[i].text, items[i].value));
}

4
Никогда не слышал об Optionобъекте раньше. Это встроено во все браузеры?
— Дэррил Хейн

2
Я попытался использовать new Option, но обнаружил, что это не работает в IE6 и 7. У меня нет причины, почему, но многие из полных опций jQuery работали.
— Дэррил Хейн

Хороший способ добавить выбор тоже. new Option('display', value, true)
— кодек

@ Mark0978 на самом деле это new Option('display', value, true, true)( javascriptkit.com/jsref/select.shtml )
— Карл Хёрберг

38

Если вам не нужно поддерживать старые версии IE, использование Optionконструктора - это, безусловно, лучший путь, удобочитаемое и эффективное решение :

$(new Option('myText', 'val')).appendTo('#mySelect');

Это эквивалентно по функциональности, но чище, чем:

$("<option></option>").attr("value", "val").text("myText")).appendTo('#mySelect');

31

Это выглядит лучше, обеспечивает удобочитаемость, но медленнее, чем другие методы.

$.each(selectData, function(i, option)
{
    $("<option/>").val(option.id).text(option.title).appendTo("#selectBox");
});

Если вам нужна скорость, самый быстрый (проверенный!) Способ - использовать массив, а не конкатенацию строк и использовать только один вызов добавления.

auxArr = [];
$.each(selectData, function(i, option)
{
    auxArr[i] = "<option value='" + option.id + "'>" + option.title + "</option>";
});

$('#selectBox').append(auxArr.join(''));

Не означает ли это, что «самым быстрым» способом было бы вставлять различные строковые части как отдельные элементы массива, вместо того, чтобы объединять составляющие каждого параметра перед вставкой в ​​массив, поскольку все они все равно будут объединены как один в конце?
— bitoolean

22

Уточнение более старого ответа @ joshperry :

Кажется, что обычный .append также работает, как и ожидалось,

$("#mySelect").append(
  $.map(selectValues, function(v,k){

    return $("<option>").val(k).text(v);
  })
);

или короче,

$("#mySelect").append(
  $.map(selectValues, (v,k) => $("<option>").val(k).text(v))
  // $.map(selectValues, (v,k) => new Option(v, k)) // using plain JS
);

Вы могли бы альтернативно использовать, $.weakmapчтобы разрешитьGC
— Chef_Code

2
Бонусные очки за элегантность: правильно использовать map()конструкцию в сочетании со свойством append()правильно добавлять массив объектов!
— Йохем Шуленклоппер

@joshperry Я немного разочарован, так как ожидал технической коррекции / обновления.
— Сухой27

20

Все эти ответы кажутся излишне сложными. Все, что тебе нужно:

var options = $('#mySelect').get(0).options;
$.each(selectValues, function(key, value) {
        options[options.length] = new Option(value, key);
});

Это полностью совместимо с браузерами.


Должно ли это быть new Option(value, key);? Порядок параметров - Параметры (text_visible_part, value_behind_the_scenes).
— Боб Стейн

Разве Array push не совместим с браузерами? Тогда, разве это не излишне сложно, когда толчок массива более читабелен?
— bitoolean

18

Будьте предупреждены ... Я использую jQuery Mobile 1.0b2 с PhoneGap 1.0.0 на телефоне Android 2.2 (Cyanogen 7.0.1) (T-Mobile G2) и не могу заставить метод .append () работать вообще. Мне пришлось использовать .html () следующим образом:

var options;
$.each(data, function(index, object) {
    options += '<option value="' + object.id + '">' + object.stop + '</option>';
});

$('#selectMenu').html(options);

18
 var output = [];
 var length = data.length;
 for(var i = 0; i < length; i++)
 {
    output[i++] = '<option value="' + data[i].start + '">' + data[i].start + '</option>';
 }

 $('#choose_schedule').get(0).innerHTML = output.join('');

Я сделал несколько тестов, и это, я считаю, делает работу быстрее всего. :П


1
.each является общеизвестно медленным по сравнению с другими способами достижения того же результата. Это то, о чем я думал и рекомендовал бы этот подход.
— Аллен Теллез

К сожалению, 90% вариантов здесь используют $ .each (). Цикл for () может дать вам гораздо больше преимуществ в управлении и производительности, даже если он менее компактен.
— HoldOffHunger

15

Есть подход, использующий подход Microsoft Templating, который в настоящее время предлагается для включения в ядро ​​jQuery. В использовании шаблонов больше возможностей, поэтому для простейшего сценария это может оказаться не лучшим вариантом. Для получения более подробной информации смотрите пост Скотта Гу с описанием возможностей.

Сначала включите шаблонный файл js, доступный на github .

<script src="Scripts/jquery.tmpl.js" type="text/javascript" />

Следующая настройка шаблона

<script id="templateOptionItem" type="text/html">
    <option value=\'{{= Value}}\'>{{= Text}}</option>
</script>

Затем с вашими данными вызовите метод .render ()

var someData = [
    { Text: "one", Value: "1" },
    { Text: "two", Value: "2" },
    { Text: "three", Value: "3"}];

$("#templateOptionItem").render(someData).appendTo("#mySelect");

Я блоге этот подход более подробно.


12

Я сделал что-то вроде этого, загружая выпадающий элемент через Ajax . Ответ выше также приемлем, но всегда полезно иметь как можно меньше модификаций DOM для лучшей производительности.

Поэтому вместо добавления каждого элемента в цикл лучше собирать элементы в цикле и добавлять его после завершения.

$(data).each(function(){
    ... Collect items
})

Добавить его,

$('#select_id').append(items); 

или даже лучше

$('#select_id').html(items);

$ ( '# select_id') HTML (элементы). работал точно так, как я хотел. используя append, он продолжает добавлять элементы во все события onchange. Огромное спасибо.
— Дипанвита Дас

10

Простой способ:

$('#SelectId').html("<option value='0'>select</option><option value='1'>Laguna</option>");

Я уже создал свой список опций, поэтому заполнение поля выбора было таким же простым, как говорит Уиллард.
— Loony2nz

10

Большинство других ответов используют eachфункцию для итерации по selectValues. Для этого требуется, чтобы append вызывался для каждого элемента, и при каждом добавлении по отдельности запускается перекомпоновка.

Обновление этого ответа до более идиоматического функционального метода (с использованием современного JS) может быть сформировано для вызова appendтолько один раз, с массивом optionэлементов, созданным с использованием map и Optionконструктора элемента.

Использование Optionэлемента DOM должно снизить накладные расходы при вызове функции, так как optionэлемент не нуждается в обновлении после создания, а логика синтаксического анализа jQuery не должна выполняться.

$('mySelect').append($.map(selectValues, (k, v) => new Option(k, v)))

Это может быть еще более упрощено, если вы создадите служебную функцию фабрики, которая создаст объект опций:

const newoption = (...args) => new Option(...args)

Тогда это может быть предоставлено непосредственно map:

$('mySelect').append($.map(selectValues, newoption))

Предыдущая формулировка

Потому что appendтакже позволяет передаче значений в качестве переменного числа аргументов, можно предварительно создать список из optionэлементов карты и добавить их в качестве аргументов в одном вызове с помощью apply.

$.fn.append.apply($('mySelect'), $.map(selectValues, (k, v) => $("<option/>").val(k).text(v)));

Похоже, что в более поздних версиях jQuery appendтакже принимает аргумент массива, и это может быть несколько упрощено:

$('mySelect').append($.map(selectValues, (k, v) => $("<option/>").val(k).text(v)))

10
function populateDropdown(select, data) {   
    select.html('');   
    $.each(data, function(id, option) {   
        select.append($('<option></option>').val(option.value).html(option.name));   
    });          
}   

Хорошо работает с jQuery 1.4.1.

Для полной статьи по использованию динамических списков с ASP.NET MVC и jQuery посетите:

Динамические списки выбора с MVC и jQuery


8

Существует проблема с сортировкой этого решения в Chrome (jQuery 1.7.1) (Chrome сортирует свойства объекта по имени / номеру?) Поэтому, чтобы сохранить порядок (да, это объект злоупотребляет), я изменил это:

optionValues0 = {"4321": "option 1", "1234": "option 2"};

к этому

optionValues0 = {"1": {id: "4321", value: "option 1"}, "2": {id: "1234", value: "option 2"}};

и тогда $ .each будет выглядеть так:

$.each(optionValues0, function(order, object) {
  key = object.id;
  value = object.value;
  $('#mySelect').append($('<option>', { value : key }).text(value));
}); 

8

Вместо того, чтобы повторять один и тот же код везде, я бы посоветовал написать собственную функцию jQuery, например:

jQuery.fn.addOption = function (key, value) {
    $(this).append($('<option>', { value: key }).text(value));
};

Затем, чтобы добавить опцию, просто сделайте следующее:

$('select').addOption('0', 'None');

Не могли бы вы уточнить?
— Пн.

7

Вы можете просто перебрать свой массив json с помощью следующего кода

$('<option/>').attr("value","someValue").text("Option1").appendTo("#my-select-id");


7

Хотя все предыдущие ответы являются действительными, может быть целесообразно сначала добавить все это в documentFragmnet, а затем добавить этот фрагмент документа как элемент после ...

Посмотрите мысли Джона Резига по этому вопросу ...

Что-то вроде:

var frag = document.createDocumentFragment();

for(item in data.Events)
{
    var option = document.createElement("option");

    option.setAttribute("value", data.Events[item].Key);
    option.innerText = data.Events[item].Value;

    frag.appendChild(option);
}
eventDrop.empty();
eventDrop.append(frag);

7
  1. $.eachмедленнее, чем forцикл
  2. Каждый раз, выбор DOM не лучшая практика в цикле $("#mySelect").append();

Таким образом, лучшее решение заключается в следующем

Если данные в формате JSON respявляется

[
    {"id":"0001", "name":"Mr. P"},
    {"id":"0003", "name":"Mr. Q"},
    {"id":"0054", "name":"Mr. R"},
    {"id":"0061", "name":"Mr. S"}
]

использовать его как

var option = "";
for (i=0; i<resp.length; i++) {
    option += "<option value='" + resp[i].id + "'>" + resp[i].name + "</option>";
}
$('#mySelect').html(option);

6

Еще один способ сделать это:

var options = [];    
$.each(selectValues, function(key, value) {
    options.push($("<option/>", {
        value: key,
        text: value
    }));
});
$('#mySelect').append(options);

Я вижу, что вы сделали здесь ... Вы воспользовались советом для кеширования, а $('#mySelect')затем реорганизовали ответ @rocktheroad ... что угодно, это более практичное решение
— Chef_Code

6
if (data.length != 0) {
    var opts = "";
    for (i in data)
        opts += "<option value='"+data[i][value]+"'>"+data[i][text]+"</option>";

    $("#myselect").empty().append(opts);
}

Это манипулирует DOM только один раз после создания гигантской нити.


Вы можете оптимизировать это дальше и вообще избежать использования jQuery, заменив $("#myselect").empty().append(opts);наgetElementById('myselect').innerHtml = opts;
— vahanpwns

6

Вот что я сделал с двумерными массивами: Первый столбец элемент я, добавить innerHTMLиз <option>. Второй столбец record_id я, добавить к valueиз <option>:

  1. PHP

    $items = $dal->get_new_items(); // Gets data from the database
    $items_arr = array();
    $i = 0;
    foreach ($items as $item)
    {
        $first_name = $item->first_name;
        $last_name = $item->last_name;
        $date = $item->date;
        $show = $first_name . " " . $last_name . ", " . $date;
        $request_id = $request->request_id;
        $items_arr[0][$i] = $show;
        $items_arr[1][$i] = $request_id;
        $i++;
    }
    
    echo json_encode($items_arr);
  2. JavaScript / Ajax

            function ddl_items() {
                if (window.XMLHttpRequest) {
                    // Code for Internet Explorer 7+, Firefox, Chrome, Opera, and Safari
                    xmlhttp=new XMLHttpRequest();
                }
                else{
                    // Code for Internet Explorer 6 and Internet Explorer 5
                    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                }
    
                xmlhttp.onreadystatechange=function() {
                if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                    var arr = JSON.parse(xmlhttp.responseText);
                    var lstbx = document.getElementById('my_listbox');
    
                    for (var i=0; i<arr.length; i++) {
                        var option = new Option(arr[0][i], arr[1][i]);
                        lstbx.options.add(option);
                    }
                }
            };
    
            xmlhttp.open("GET", "Code/get_items.php?dummy_time=" + new Date().getTime() + "", true);
            xmlhttp.send();
        }
    }

Выглядит хорошо. Жаль, что он не использует jQuery. Кроме того, раньше у меня были проблемы с методом select.options.add (). Не могу вспомнить, какой браузер и какая именно проблема, но я решил уйти от этого и позволить jQuery разобраться с различиями.
— Дэррил Хейн

Я полный нуб с PHP и JQuerry, но приведенный выше код работает во всех браузерах. единственная проблема - это не работает на iPhone, я отправил вопрос об этом, пока не повезло :( stackoverflow.com/questions/11364040/…
— Соленый


5

Я обнаружил, что это просто и прекрасно работает.

for (var i = 0; i < array.length; i++) {
    $('#clientsList').append($("<option></option>").text(array[i].ClientName).val(array[i].ID));
};

4

Формат JSON:

[{
    "org_name": "Asset Management"
}, {
    "org_name": "Debt Equity Foreign services"
}, {
    "org_name": "Credit Services"
}]

И код jQuery для заполнения значений в раскрывающемся списке Ajax:

success: function(json) {
    var options = [];
    $('#org_category').html('');  // Set the Dropdown as Blank before new Data
    options.push('<option>-- Select Category --</option>');
    $.each(JSON.parse(json), function(i, item) {
        options.push($('<option/>',
        {
           value: item.org_name, text: item.org_name
        }));
    });
    $('#org_category').append(options);  // Set the Values to Dropdown
}

3

Используя функцию $ .map (), вы можете сделать это более элегантным способом:

$('#mySelect').html( $.map(selectValues, function(val, key){
    return '<option value="' + val + '">'+ key + '</option>';
}).join(''));

Это немного короче, но одна проблема связана с выходом из val и key vars, что делает принятый ответ.
— Дэррил Хейн

2
<!DOCTYPE html>
<html lang="en">
<head>
  <title>append selectbox using jquery</title>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <script type="text/javascript">
    function setprice(){
        var selectValues = { "1": "test 1", "2": "test 2" };
        $.each(selectValues, function(key, value) {   
     $('#mySelect')
         .append($("<option></option>")
                    .attr("value",key)
                    .text(value)); 
});

    }
  </script>
</head>
<body onload="setprice();">


      <select class="form-control" id="mySelect">
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
  </select>


</body>
</html>

2

Установите свой HTML select id в следующую строку ниже. Здесь mySelectиспользуется как идентификатор элемента select.

   var options = $("#mySelect");

затем получите объект, который является selectValues ​​в этом сценарии, и установите его в jquery для каждого цикла. Он будет использовать значение и текст объектов соответственно и добавляет его в варианты выбора следующим образом.

$.each(selectValues, function(val, text) {
            options.append(
             $('<option></option>').val(val).html(text)
          );
      });

Текст будет отображаться в виде списка параметров, если выбран раскрывающийся список, и после выбора текста будет использоваться значение выбранного текста.

Например.

«1»: «тест 1», «2»: «тест 2»,

Падать,

отображаемое имя: тест 1 -> значение равно 1 отображаемое имя: тест 2 -> значение равно 2


пожалуйста, опишите немного о решении.
— Винай Праджапати

2

На самом деле, для повышения производительности лучше составить список опций отдельно и добавить идентификатор.

var options = [];
$.each(selectValues, function(key, value) {
    options.push ($('<option>', { value : key })
          .text(value));
});
 $('#mySelect').append(options);

http://learn.jquery.com/performance/append-outside-loop/

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.