Каков наилучший способ добавить параметры для выбора в качестве объекта 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)); 
});
matdumsa
источник
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 () метод)

gpilotino
источник
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>

rocktheroad
источник
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');
Nickolay
источник
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(''));
m1sfit
источник
Не означает ли это, что «самым быстрым» способом было бы вставлять различные строковые части как отдельные элементы массива, вместо того, чтобы объединять составляющие каждого параметра перед вставкой в ​​массив, поскольку все они все равно будут объединены как один в конце?
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
);
Сухой27
источник
Вы могли бы альтернативно использовать, $.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('');

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

Teej
источник
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);
Komang
источник
$ ( '# 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)))
joshperry
источник
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

H Sampat
источник
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));
}); 
Michail
источник
8

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

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

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

$('select').addOption('0', 'None');
Matt
источник
Не могли бы вы уточнить?
Пн.
7

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

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

Kashif
источник
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);
Stuart.Sklinar
источник
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);
MaxEcho
источник
6

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

var options = [];    
$.each(selectValues, function(key, value) {
    options.push($("<option/>", {
        value: key,
        text: value
    }));
});
$('#mySelect').append(options);
DiverseAndRemote.com
источник
Я вижу, что вы сделали здесь ... Вы воспользовались советом для кеширования, а $('#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));
};
DW333
источник
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
}
MJ
источник
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/

Шохан
источник