Каков наилучший способ добавления параметров в <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>');
}
}
Чистое / простое решение:
Это очищенный и упрощенный версия матдумсы:
$.each(selectValues, function(key, value) {
$('#mySelect')
.append($('<option>', { value : key })
.text(value));
});
Отличия от matdumsa: (1) удален закрывающий тег для параметра внутри append () и (2) перенесены свойства / атрибуты на карту в качестве второго параметра append ().
Перечисленная выше очищенная версия работает только в JQuery 1.4+. Для более старых версий используйте тот, который указан в ответе matdumsa
{value: key} должно быть {"value": key}, как видно из ответа matdumsa.
Я не верю в это, поскольку value - это строка (и жестко закодированная), ее не нужно заключать в кавычки.
может быть это вам поможет - kvcodes.com/2016/10/…
Вместо этого заголовок должен быть следующим: «Как лучше всего добавить параметры для выбора из объекта JSON с помощью jQuery?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Так же, как и другие ответы, в стиле jQuery:
$.each(selectValues, function(key, value) {
$('#mySelect')
.append($("<option></option>")
.attr("value", key)
.text(value));
});
Я бы в первую очередь назначил $("#mySelect") переменной, иначе вызов $("#mySelect") каждый раз внутри цикла очень расточителен, как и обновление DOM. См. Пункты № 3 и № 6 в artzstudio.com/2009/04/jquery-performance-rules/….
@Patrick Итак, каково ваше решение этого вопроса, Патрик? Скажем, у вас есть группа элементов, как вы с этим справляетесь? (Вставьте "$ ('# mySelect')" его "$ ('. Xxx')", чтобы вы получили группу списка выбора.)
ну, вы могли бы просто сделать цикл var mySelect = $("#mySelect") outside of the each`. Это было бы намного эффективнее. См. Ответ Карла ниже
Моя рекомендация по выбору лучшего стиля jQuery: $ ('# mySelect') .append ($ ("<option />") .val (key) .text (value));
Я не понимаю этого, потому что $('#mySelect').append('<option></option>') возвращает элемент select, а не только что добавленный option. Таким образом, цепочка будет на select, а не на option, и мы не хотим устанавливать значение и текст для выбора - мы хотим сделать это для опции.
Мэтт, проверь вложенность скобок. .Append () находится в выборе, все остальное находится внутри добавления. $ ("<option />") - это сокращение jquery для создания нового элемента option, и .val (ключ) и .text (значение) применяются к этому новому параметру, который затем добавляется к выбранному. (Я имею в виду более сжатый синтаксис Flo в комментарии над вашим, но то же самое верно и в отношении ответа верхнего уровня.)
Учитывая популярность этого ответа, стоит упомянуть, что вам следует избегать циклических обновлений DOM. jsperf.com/jquery-append-array-vs-string
этот ответ был настолько вводящим в заблуждение из-за неправильного намерения ... attr и text на самом деле являются методами объекта $('<option/>')
В этом ответе используются устаревшие методы jQuery, он смехотворно неэффективен и по-прежнему составляет 90% репутации респондентов. Stackoverflow далеко не сломан, но для сайта это ужасно.
Это хорошее решение, но не такое производительное :( DOM вызывается много раз, в зависимости от размера вашего списка объектов, ИМХО, вам следует избегать этого, если вы действительно заботитесь о производительности.
Это ужасно использовать в реальных случаях! Если у вас более 100 элементов, все станет беспорядочно! Никогда не используйте его для чего-то вроде данных о стране. Лучше создать строку HTML и добавить ее после завершения цикла! :)
Мое дополнительное предложение по кешированию $('#mySelect') - использование цикла for вместо $.each().
Я сделал что-то вроде этого, загрузка выпадающего списка через Ajax. Вышеупомянутый ответ также приемлем, но всегда хорошо иметь как можно меньше модификаций DOM для повышения производительности.
Поэтому вместо того, чтобы добавлять каждый элемент внутри цикла, лучше собирать элементы внутри цикла и добавлять его после его завершения.
$(data).each(function(){
... Collect items
})
Добавьте это,
$('#select_id').append(items);
или даже лучше
$('#select_id').html(items);
$ ('# select_id'). html (элементы); работал именно так, как я хотел. используя append, он продолжает добавлять элементы во все событие onchange. Большое спасибо.
Если вам не нужно поддерживать старые версии IE, очевидно, что использование Конструктор Option - лучший вариант, удобочитаемое и эффективное решение:
$(new Option('myText', 'val')).appendTo('#mySelect');
По функциональности он эквивалентен, но чище, чем:
$("<option></option>").attr("value", "val").text("myText")).appendTo('#mySelect');
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 () метод)
Ваш метод, очевидно, быстрее, чем «правильный» ответ выше, поскольку он также использует меньше jQuery.
строка "$ ('# mySelect'). get (0) .innerHTML = output.join ('');" работает в Chrome и FF3.x, но не в IE7, насколько я могу судить
Это не работает, если в key есть какие-то кавычки или >, <.
если в ключе есть кавычки или <или>, значит HTML недействителен. собственный innerHTML быстрее, чем использование jquery html ().
И, если у меня есть два варианта, я не хочу их терять. Как я могу добавить эти новые значения параметров к существующим?
Одно небольшое улучшение - объединение с использованием соединения, а не знака плюса, например: output.push ('<option value = "', key, '">', value, '</option>');
+1 это решение, но $ .each стало НОВЫМ узким местом. Замените его старомодным циклом for, где / если применимо: jsperf.com/for-vs-foreach/37
Если вам не нужно поддерживать IE8, то собственный Array.forEach станет хорошей заменой для $ .each.
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('');
Я провел несколько тестов, и я считаю, что это работает быстрее всего. :П
.each, как известно, медленный по сравнению с другими способами достижения того же результата. Это то, о чем я думал, и рекомендую этот подход.
К сожалению, 90% вариантов здесь используют $ .each (). Цикл for () может дать вам гораздо больше контроля и повышения производительности, даже если он менее компактен.
Это выглядит лучше, обеспечивает удобочитаемость, но работает медленнее, чем другие методы.
$.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(''));
Разве это не означает, что «самым быстрым» способом будет также вставка различных частей строки как отдельных элементов массива, вместо того, чтобы объединять составляющие каждого параметра перед вставкой в массив, поскольку все они в любом случае будут объединены в один в конце?
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, посетите:
Самый простой способ:
$('#SelectId').html("<option value='0'>select</option><option value='1'>Laguna</option>");
Я уже создал свой список опций, поэтому заполнить поле выбора было так же просто, как говорит Уиллард.
Это немного быстрее и чище.
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>Идеальный. Чтобы добавить к нему, могут быть добавлены дополнительные атрибуты для выбора. $ .each (selectValues, function (id, value, text) {$ ('# mySelect'). append ($ ("<option />", {id: id value: value, text: text}));} );
Думаю, будет лучше кешировать `$ ('# mySelect')`, чтобы вы смотрели только один раз перед циклом. В настоящее время он ищет в DOM элемент для каждой отдельной опции.
@ Sushanth - насколько это сильно ударит по производительности, если набор небольшой?
@ckarbass - зависит от размера вашего DOM. Потенциально большие и очень небольшие усилия для присвоения его переменной, значительно меньше, чем написание комментария в SO!
Существует подход с использованием Подход 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");
У меня блоггинг этот подход более подробно.
Вы можете просто перебрать свой массив json с помощью следующего кода
$('<option/>').attr("value","someValue").text("Option1").appendTo("#my-select-id");
В большинстве других ответов используется функция each для перебора selectValues. Для этого требуется, чтобы добавление было вызвано для каждого элемента, и перекомпоновка запускалась, когда каждый добавлялся индивидуально.
Обновление этого ответа до более идиоматического функционального метода (с использованием современного JS) может быть сформировано для вызова append только один раз, с массивом элементов option, созданным с использованием карта и конструктора элементов Option.
Использование элемента DOM Option должно уменьшить накладные расходы на вызов функции, поскольку элемент option не нужно обновлять после создания, а логика синтаксического анализа jQuery не требуется.
$('mySelect').append($.map(selectValues, (k, v) => new Option(k, v)))
Это можно упростить еще больше, если вы создадите служебную функцию factory, которая будет обновлять объект option:
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)))
Плагин jQuery можно найти здесь: Автоматическое заполнение полей выбора с помощью jQuery и AJAX.
var list = $("#selectList");
$.each(items, function(index, item) {
list.append(new Option(item.text, item.value));
});
var list = document.getElementById("selectList");
for(var i in items) {
list.add(new Option(items[i].text, items[i].value));
}
Никогда раньше не слышал об объекте Option. Это встроено во все браузеры?
Я попытался использовать new Option, но обнаружил, что он не работает в IE6 и 7. У меня нет причины, почему, но многие из полных параметров jQuery работали.
Хороший способ добавить выделение. new Option('display', value, true)
@ Mark0978 на самом деле это new Option('display', value, true, true) (javascriptkit.com/jsref/select.shtml)
@ CarlHörberg, который отлично сработал для меня - очень просто! Благодарность!
Предупреждаем ... Я использую 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);
Я обнаружил, что это просто и отлично работает.
for (var i = 0; i < array.length; i++) {
$('#clientsList').append($("<option></option>").text(array[i].ClientName).val(array[i].ID));
};
Вот что я сделал с двумерными массивами: первый столбец - это элемент i, добавляемый к innerHTML из <option>. Второй столбец - record_id i, добавьте к value из <option>:
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);
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, но приведенный выше код работает во всех браузерах. единственная проблема - не работает на айфоне, я задал вопрос по этому поводу, пока не повезло :( stackoverflow.com/questions/11364040/…
Проблема с сортировкой этого решения в 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));
});
Хотя все предыдущие ответы являются действительными ответами - может быть целесообразно сначала добавить все это в 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);
Доработка старого @ ответ Джошперри:
Кажется, что обычный .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
Бонус за элегантность: правильное использование конструкции map() в сочетании со свойством append() для правильного добавления массива объектов!
@joshperry Я немного разочарован, так как ожидал технических исправлений / обновлений.
Еще один способ сделать это:
var options = [];
$.each(selectValues, function(key, value) {
options.push($("<option/>", {
value: key,
text: value
}));
});
$('#mySelect').append(options);
Я вижу, что вы здесь сделали ... Вы последовали совету кешировать $('#mySelect'), а затем отредактировали ответ @rocktheroad ... как бы то ни было, это более практичное решение
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;
Все эти ответы кажутся излишне сложными. Все, что тебе нужно:
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 не совместим с несколькими браузерами? Тогда, разве это не излишне сложно, когда Array push более читабелен?
$.each медленнее, чем петля for$("#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);
Я объединяю два лучших ответа в отличный ответ.
var outputConcatenation = [];
$.each(selectValues, function(i, item) {
outputConcatenation.push($("<option></option>").attr("value", item.key).attr("data-customdata", item.customdata).text(item.text).prop("outerHTML"));
});
$("#myselect").html(outputConcatenation.join(''));
Вместо того, чтобы везде повторять один и тот же код, я бы посоветовал написать свою собственную функцию jQuery, например:
jQuery.fn.addOption = function (key, value) {
$(this).append($('<option>', { value: key }).text(value));
};
Затем, чтобы добавить опцию, просто сделайте следующее:
$('select').addOption('0', 'None');
Не могли бы вы уточнить?
Формат 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
}
Используя функцию $ .map (), вы можете сделать это более элегантно:
$('#mySelect').html( $.map(selectValues, function(val, key){
return '<option value = "' + val + '">'+ key + '</option>';
}).join(''));
Это немного короче, но одна проблема связана с экранированием переменных val и key, что и делает принятый ответ.
$.each(selectValues, function(key, value) {
$('#mySelect').append($("<option/>", {
value: key, text: value
}));
});
<!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>
Задайте идентификатор выбора HTML в следующей строке ниже. Здесь 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
пожалуйста, опишите немного о решении.
Я решил немного вмешаться.
multiple при добавлении дополнительных опций// objects as value/desc
let selectValues = {
"1": "test 1",
"2": "test 2",
"3": "test 3",
"4": "test Four"
};
//use div here as using "select" mucks up the original selected value in "mySelect"
let opts = $("<div />");
let opt = {};
$.each(selectValues, function(value, desc) {
opts.append($('<option />').prop("value", value).text(desc));
});
opts.find("option").appendTo('#mySelect');
// array of objects called "options" in an object
let selectValuesNew = {
options: [{
value: "1",
description: "2test 1"
},
{
value: "2",
description: "2test 2",
selected: true
},
{
value: "3",
description: "2test 3"
},
{
value: "4",
description: "2test Four"
}
]
};
//use div here as using "select" mucks up the original selected value
let opts2 = $("<div />");
let opt2 = {}; //only append after adding all options
$.map(selectValuesNew.options, function(val, index) {
opts2.append($('<option />')
.prop("value", val.value)
.prop("selected", val.selected)
.text(val.description));
});
opts2.find("option").appendTo('#mySelectNew');<script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id = "mySelect">
<option value = "" selected = "selected">empty</option>
</select>
<select id = "mySelectNew" multiple = "multiple">
<option value = "" selected = "selected">2empty</option>
</select>На самом деле, для повышения производительности лучше составить список опций отдельно и добавить его к выбору id.
var options = [];
$.each(selectValues, function(key, value) {
options.push ($('<option>', { value : key })
.text(value));
});
$('#mySelect').append(options);
Поскольку JQuery append может принимать массив в качестве аргумента, я удивлен, что никто не предложил сделать это однострочным с map.
$('#the_select').append(['a','b','c'].map(x => $('<option>').text(x)));
или reduce
['a','b','c'].reduce((s,x) => s.append($('<option>').text(x)), $('#the_select'));
Получение ключей объекта для получения значений объекта. Использование map () для добавления новых опций.
const selectValues = {
"1": "test 1",
"2": "test 2"
}
const selectTest = document.getElementById('selectTest')
Object.keys(selectValues).map(key => selectTest.add(new Option(selectValues[key], key)))<select id = "selectTest"></select>В чистом JS добавление следующей опции для выбора проще и проще
mySelect.innerHTML+= `<option value = "${key}">${value}</option>`;
let selectValues = { "1": "test 1", "2": "test 2" };
for(let key in selectValues) {
mySelect.innerHTML+= `<option value = "${key}">${selectValues[key]}</option>`;
}<select id = "mySelect">
<option value = "0" selected = "selected">test 0</option>
</select>
возможно, поможет: texotela.co.uk/code/jquery/select (мне помогло после того, как я наткнулся на этот вопрос)