Javascript для сортировки содержимого элемента select
есть ли быстрый способ сортировки элементов выбранного элемента?
Или мне нужно прибегнуть к написанию javascript?
Пожалуйста, любые идеи.
<select size="4" name="lstALL" multiple="multiple" id="lstALL" tabindex="12" style="font-size:XX-Small;height:95%;width:100%;">
<option value="0"> XXX</option>
<option value="1203">ABC</option>
<option value="1013">MMM</option>
</select>
Ответы
Ответ 1
Это сделает трюк. Просто передайте ему свой элемент select a la: document.getElementById('lstALL')
, когда вам нужно отсортировать список.
function sortSelect(selElem) {
var tmpAry = new Array();
for (var i=0;i<selElem.options.length;i++) {
tmpAry[i] = new Array();
tmpAry[i][0] = selElem.options[i].text;
tmpAry[i][1] = selElem.options[i].value;
}
tmpAry.sort();
while (selElem.options.length > 0) {
selElem.options[0] = null;
}
for (var i=0;i<tmpAry.length;i++) {
var op = new Option(tmpAry[i][0], tmpAry[i][1]);
selElem.options[i] = op;
}
return;
}
Ответ 2
Это решение работало очень хорошо для меня, используя jquery, подумал, что я перекрестю ссылку на него здесь, когда я нашел эту страницу перед другой. Кто-то другой может сделать то же самое.
$("#id").html($("#id option").sort(function (a, b) {
return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
}))
из Сортировка выпадающего списка с использованием Javascript
Ответ 3
Из Часто задаваемые вопросы W3C:
Хотя во многих языках программирования есть такие устройства, как раскрывающиеся окна, которые могут сортировать список элементов, прежде чем отображать их как часть их функциональных возможностей, HTML <select> функция не имеет таких возможностей. В нем перечислены параметры <options> в полученном порядке.
Вам придется сортировать их вручную для статического документа HTML или использовать Javascript или какой-либо другой программный вид для динамического документа.
Ответ 4
У меня была та же проблема. Здесь решение jQuery я придумал:
var options = jQuery.makeArray(optionElements).
sort(function(a,b) {
return (a.innerHTML > b.innerHTML) ? 1 : -1;
});
selectElement.html(options);
Ответ 5
Другая опция:
function sortSelect(elem) {
var tmpAry = [];
// Retain selected value before sorting
var selectedValue = elem[elem.selectedIndex].value;
// Grab all existing entries
for (var i=0;i<elem.options.length;i++) tmpAry.push(elem.options[i]);
// Sort array by text attribute
tmpAry.sort(function(a,b){ return (a.text < b.text)?-1:1; });
// Wipe out existing elements
while (elem.options.length > 0) elem.options[0] = null;
// Restore sorted elements
var newSelectedIndex = 0;
for (var i=0;i<tmpAry.length;i++) {
elem.options[i] = tmpAry[i];
if(elem.options[i].value == selectedValue) newSelectedIndex = i;
}
elem.selectedIndex = newSelectedIndex; // Set new selected index after sorting
return;
}
Ответ 6
Работая с ответами Марко Лаззери и Терре Портера (проголосуйте, если этот ответ будет полезен), я придумал немного другое решение, которое сохраняет выбранное значение (вероятно, не сохраняет обработчики событий или прикрепленные данные, хотя), используя jQuery.
// save the selected value for sorting
var v = jQuery("#id").val();
// sort the options and select the value that was saved
j$("#id")
.html(j$("#id option").sort(function(a,b){
return a.text == b.text ? 0 : a.text < b.text ? -1 : 1;}))
.val(v);
Ответ 7
Это перекомпиляция моих 3 любимых ответов на этой доске:
- jOk лучший и самый простой ответ.
- Терри Портер - простой метод jQuery.
- Конфигурируемая функция SmokeyPHP.
Результаты представляют собой простую в использовании и легко настраиваемую функцию.
Первый аргумент может быть выбранным объектом, идентификатором выбранного объекта или массивом с не менее чем двумя измерениями.
Второй аргумент является необязательным. По умолчанию сортировка по опции text, index 0. Может быть передан любой другой индекс, поэтому сортировка по нему. Может быть передано 1 или текстовое "значение" для сортировки по значению.
Сортировка по текстовым примерам (все будут сортироваться по тексту):
sortSelect('select_object_id');
sortSelect('select_object_id', 0);
sortSelect(selectObject);
sortSelect(selectObject, 0);
Сортировка по значению (все будут сортироваться по значению):
sortSelect('select_object_id', 'value');
sortSelect('select_object_id', 1);
sortSelect(selectObject, 1);
Сортировка любого массива по другому индексу:
var myArray = [
['ignored0', 'ignored1', 'Z-sortme2'],
['ignored0', 'ignored1', 'A-sortme2'],
['ignored0', 'ignored1', 'C-sortme2'],
];
sortSelect(myArray,2);
Этот последний будет сортировать массив по индексу-2, сортировке.
Основная функция сортировки
function sortSelect(selElem, sortVal) {
// Checks for an object or string. Uses string as ID.
switch(typeof selElem) {
case "string":
selElem = document.getElementById(selElem);
break;
case "object":
if(selElem==null) return false;
break;
default:
return false;
}
// Builds the options list.
var tmpAry = new Array();
for (var i=0;i<selElem.options.length;i++) {
tmpAry[i] = new Array();
tmpAry[i][0] = selElem.options[i].text;
tmpAry[i][1] = selElem.options[i].value;
}
// allows sortVal to be optional, defaults to text.
switch(sortVal) {
case "value": // sort by value
sortVal = 1;
break;
default: // sort by text
sortVal = 0;
}
tmpAry.sort(function(a, b) {
return a[sortVal] == b[sortVal] ? 0 : a[sortVal] < b[sortVal] ? -1 : 1;
});
// removes all options from the select.
while (selElem.options.length > 0) {
selElem.options[0] = null;
}
// recreates all options with the new order.
for (var i=0;i<tmpAry.length;i++) {
var op = new Option(tmpAry[i][0], tmpAry[i][1]);
selElem.options[i] = op;
}
return true;
}
Ответ 8
Да DOK имеет правильный ответ... либо предварительно сортировать результаты до того, как вы напишете HTML (считая его динамическим, и вы несете ответственность за вывод), либо напишите javascript.
Javascript Sort будет вашим другом здесь. Просто вытащите значения из списка выбора, затем выполните сортировку и верните их: -)
Ответ 9
Í думаю, что это лучший вариант (я использую код @Matty и улучшен!):
function sortSelect(selElem, bCase) {
var tmpAry = new Array();
bCase = (bCase ? true : false);
for (var i=0;i<selElem.options.length;i++) {
tmpAry[i] = new Array();
tmpAry[i][0] = selElem.options[i].text;
tmpAry[i][1] = selElem.options[i].value;
}
if (bCase)
tmpAry.sort(function (a, b) {
var ret = 0;
var iPos = 0;
while (ret == 0 && iPos < a.length && iPos < b.length)
{
ret = (String(a).toLowerCase().charCodeAt(iPos) - String(b).toLowerCase().charCodeAt(iPos));
iPos ++;
}
if (ret == 0)
{
ret = (String(a).length - String(b).length);
}
return ret;
});
else
tmpAry.sort();
while (selElem.options.length > 0) {
selElem.options[0] = null;
}
for (var i=0;i<tmpAry.length;i++) {
var op = new Option(tmpAry[i][0], tmpAry[i][1]);
selElem.options[i] = op;
}
return;
}
Ответ 10
Я использовал эту сортировку пузырьков, потому что я не смог заказать их по .value в массиве опций, и это был номер. Таким образом, я получил их должным образом. Я надеюсь, что это тоже полезно для вас.
function sortSelect(selElem) {
for (var i=0; i<(selElem.options.length-1); i++)
for (var j=i+1; j<selElem.options.length; j++)
if (parseInt(selElem.options[j].value) < parseInt(selElem.options[i].value)) {
var dummy = new Option(selElem.options[i].text, selElem.options[i].value);
selElem.options[i] = new Option(selElem.options[j].text, selElem.options[j].value);
selElem.options[j] = dummy;
}
}
Ответ 11
У меня была аналогичная проблема, за исключением того, что я хотел, чтобы выбранные элементы отображались вверху, и я не хотел очищать элементы, которые были выбраны (список с несколькими выборами). Mine основано на jQuery...
function SortMultiSelect_SelectedTop(slt) {
var options =
$(slt).find("option").sort(function (a, b) {
if (a.selected && !b.selected) return -1;
if (!a.selected && b.selected) return 1;
if (a.text < b.text) return -1;
if (a.text > b.text) return 1;
return 0;
});
$(slt).empty().append(options).scrollTop(0);
}
Без выбора сверху это будет выглядеть так.
function SortMultiSelect(slt) {
var options =
$(slt).find("option").sort(function (a, b) {
if (a.text < b.text) return -1;
if (a.text > b.text) return 1;
return 0;
});
$(slt).empty().append(options).scrollTop(0);
}
Ответ 12
Я быстро собрал один, который позволяет выбирать направление ( "asc" или "desc" ), должно ли сравнение выполняться над значением параметра (true или false) и должно ли начальное и конечное пробелы быть обрезано перед сравнением (булево).
Преимущество этого метода состоит в том, что выбранный выбор сохраняется, и все остальные специальные свойства/триггеры также должны сохраняться.
function sortOpts(select,dir,value,trim)
{
value = typeof value == 'boolean' ? value : false;
dir = ['asc','desc'].indexOf(dir) > -1 ? dir : 'asc';
trim = typeof trim == 'boolean' ? trim : true;
if(!select) return false;
var opts = select.getElementsByTagName('option');
var options = [];
for(var i in opts)
{
if(parseInt(i)==i)
{
if(trim)
{
opts[i].innerHTML = opts[i].innerHTML.replace(/^\s*(.*)\s*$/,'$1');
opts[i].value = opts[i].value.replace(/^\s*(.*)\s*$/,'$1');
}
options.push(opts[i]);
}
}
options.sort(value ? sortOpts.sortVals : sortOpts.sortText);
if(dir == 'desc') options.reverse();
options.reverse();
for(var i in options)
{
select.insertBefore(options[i],select.getElementsByTagName('option')[0]);
}
}
sortOpts.sortText = function(a,b) {
return a.innerHTML > b.innerHTML ? 1 : -1;
}
sortOpts.sortVals = function(a,b) {
return a.value > b.value ? 1 : -1;
}
Ответ 13
Вдохновленный ответом @Terre Porter, я думаю, что это очень просто реализовать (используя jQuery)
var $options = jQuery("#my-dropdownlist-id > option");
// or jQuery("#my-dropdownlist-id").find("option")
$options.sort(function(a, b) {
return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
})
Но для выпадающих списков Alpha/Numeric:
Вдохновленный: fooobar.com/questions/13499/...
var $options = jQuery(dropDownList).find("option");
var reAlpha = /[^a-zA-Z]/g;
var reNumeric = /[^0-9]/g;
$options.sort(function AlphaNumericSort($a,$b) {
var a = $a.text;
var b = $b.text;
var aAlpha = a.replace(reAlpha, "");
var bAlpha = b.replace(reAlpha, "");
if(aAlpha === bAlpha) {
var aNumeric = parseInt(a.replace(reNumeric, ""), 10);
var bNumeric = parseInt(b.replace(reNumeric, ""), 10);
return aNumeric === bNumeric ? 0 : aNumeric > bNumeric ? 1 : -1;
} else {
return aAlpha > bAlpha ? 1 : -1;
}
})
Надеюсь, что это поможет
![First example]()
![Second example]()
Ответ 14
function call() {
var x = document.getElementById("mySelect");
var optionVal = new Array();
for (i = 0; i < x.length; i++) {
optionVal.push(x.options[i].text);
}
for (i = x.length; i >= 0; i--) {
x.remove(i);
}
optionVal.sort();
for (var i = 0; i < optionVal.length; i++) {
var opt = optionVal[i];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
x.appendChild(el);
}
}
Идея состоит в том, чтобы вывести все элементы selectbox в массив, удалить значения selectbox, чтобы избежать переопределения, отсортировать массив и затем отбросить отсортированный массив в поле выбора
Ответ 15
Не так красиво, как пример JQuery от Marco, но с прототипом (возможно, мне не хватает более элегантного решения):
function sort_select(select) {
var options = $A(select.options).sortBy(function(o) { return o.innerHTML });
select.innerHTML = "";
options.each(function(o) { select.insert(o); } );
}
И затем просто передайте ему элемент select:
sort_select( $('category-select') );
Ответ 16
Еще один способ сделать это с помощью jQuery:
// sorting;
var selectElm = $("select"),
selectSorted = selectElm.find("option").toArray().sort(function (a, b) {
return (a.innerHTML.toLowerCase() > b.innerHTML.toLowerCase()) ? 1 : -1;
});
selectElm.empty();
$.each(selectSorted, function (key, value) {
selectElm.append(value);
});
Ответ 17
Попробуйте это... надеюсь, он предложит вам решение:
function sortlist_name()
{
var lb = document.getElementById('mylist');
arrTexts = new Array();
newTexts = new Array();
txt = new Array();
newArray =new Array();
for(i=0; i<lb.length; i++)
{
arrTexts[i] = lb.options[i].text;
}
for(i=0;i<arrTexts.length; i++)
{
str = arrTexts[i].split(" -> ");
newTexts[i] = str[1]+' -> '+str[0];
}
newTexts.sort();
for(i=0;i<newTexts.length; i++)
{
txt = newTexts[i].split(' -> ');
newArray[i] = txt[1]+' -> '+txt[0];
}
for(i=0; i<lb.length; i++)
{
lb.options[i].text = newArray[i];
lb.options[i].value = newArray[i];
}
}
/***********revrse by name******/
function sortreverse_name()
{
var lb = document.getElementById('mylist');
arrTexts = new Array();
newTexts = new Array();
txt = new Array();
newArray =new Array();
for(i=0; i<lb.length; i++)
{
arrTexts[i] = lb.options[i].text;
}
for(i=0;i<arrTexts.length; i++)
{
str = arrTexts[i].split(" -> ");
newTexts[i] = str[1]+' -> '+str[0];
}
newTexts.reverse();
for(i=0;i<newTexts.length; i++)
{
txt = newTexts[i].split(' -> ');
newArray[i] = txt[1]+' -> '+txt[0];
}
for(i=0; i<lb.length; i++)
{
lb.options[i].text = newArray[i];
lb.options[i].value = newArray[i];
}
}
function sortlist_id() {
var lb = document.getElementById('mylist');
arrTexts = new Array();
for(i=0; i<lb.length; i++) {
arrTexts[i] = lb.options[i].text;
}
arrTexts.sort();
for(i=0; i<lb.length; i++) {
lb.options[i].text = arrTexts[i];
lb.options[i].value = arrTexts[i];
}
}
/***********revrse by id******/
function sortreverse_id() {
var lb = document.getElementById('mylist');
arrTexts = new Array();
for(i=0; i<lb.length; i++) {
arrTexts[i] = lb.options[i].text;
}
arrTexts.reverse();
for(i=0; i<lb.length; i++) {
lb.options[i].text = arrTexts[i];
lb.options[i].value = arrTexts[i];
}
}
</script>
ID<a href="javascript:sortlist_id()"> ▲ </a> <a href="javascript:sortreverse_id()">▼</a> | Name<a href="javascript:sortlist_name()"> ▲ </a> <a href="javascript:sortreverse_name()">▼</a><br/>
<select name=mylist id=mylist size=8 style='width:150px'>
<option value="bill">4 -> Bill</option>
<option value="carl">5 -> Carl</option>
<option value="Anton">1 -> Anton</option>
<option value="mike">2 -> Mike</option>
<option value="peter">3 -> Peter</option>
</select>
<br>
Ответ 18
function sortItems(c) {
var options = c.options;
Array.prototype.sort.call(options, function (a, b) {
var aText = a.text.toLowerCase();
var bText = b.text.toLowerCase();
if (aText < bText) {
return -1;
} else if (aText > bText) {
return 1;
} else {
return 0;
}
});
}
sortItems(document.getElementById('lstALL'));
Ответ 19
Пример сортировки опций локализации Vanilla JS es6
const optionNodes = Array.from(selectNode.children);
const comparator = new Intl.Collator(lang.slice(0, 2)).compare;
optionNodes.sort((a, b) => comparator(a.textContent, b.textContent));
optionNodes.forEach((option) => selectNode.appendChild(option));
Мой вариант использования состоял в том, чтобы локализовать раскрывающийся список выбора страны с помощью сортировки с учетом локали. Это использовалось на 250 + опциях и было очень эффективным ~ 10 мс на моей машине.
Ответ 20
Для тех, кто ищет сортировку, есть или нет optgroup :
/**
* Sorting options
* and optgroups
*
* @param selElem select element
* @param optionBeforeGroup ?bool if null ignores, if true option appear before group else option appear after group
*/
function sortSelect(selElem, optionBeforeGroup = null) {
let initialValue = selElem.tagName === "SELECT" ? selElem.value : null;
let allChildrens = Array.prototype.slice.call(selElem.childNodes);
let childrens = [];
for (let i = 0; i < allChildrens.length; i++) {
if (allChildrens[i].parentNode === selElem && ["OPTGROUP", "OPTION"].includes(allChildrens[i].tagName||"")) {
if (allChildrens[i].tagName == "OPTGROUP") {
sortSelect(allChildrens[i]);
}
childrens.push(allChildrens[i]);
}
}
childrens.sort(function(a, b){
let x = a.tagName == "OPTGROUP" ? a.getAttribute("label") : a.innerHTML;
let y = b.tagName == "OPTGROUP" ? b.getAttribute("label") : b.innerHTML;
x = typeof x === "undefined" || x === null ? "" : (x+"");
y = typeof y === "undefined" || y === null ? "" : (y+"");
if (optionBeforeGroup === null) {
if (x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
if (x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
} else if (optionBeforeGroup === true) {
if ((a.tagName == "OPTION" && b.tagName == "OPTGROUP") || x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
if ((a.tagName == "OPTGROUP" && b.tagName == "OPTION") || x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
} else if (optionBeforeGroup === false) {
if ((a.tagName == "OPTGROUP" && b.tagName == "OPTION") || x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
if ((a.tagName == "OPTION" && b.tagName == "OPTGROUP") || x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
}
return 0;
});
if (optionBeforeGroup !== null) {
childrens.sort(function(a, b){
if (optionBeforeGroup === true) {
if (a.tagName == "OPTION" && b.tagName == "OPTGROUP") {return -1;}
if (a.tagName == "OPTGROUP" && b.tagName == "OPTION") {return 1;}
} else {
if (a.tagName == "OPTGROUP" && b.tagName == "OPTION") {return -1;}
if (a.tagName == "OPTION" && b.tagName == "OPTGROUP") {return 1;}
}
return 0;
});
}
selElem.innerHTML = "";
for (let i = 0; i < childrens.length; i++) {
selElem.appendChild(childrens[i]);
}
if (selElem.tagName === "SELECT") {
selElem.value = initialValue;
}
}