Reputation: 483
I can't figure out how to sort my select option values correctely. My select element is returning the text values as followed :
** Please choose
2-3 pers.
16-18 pers.
20-24 pers
3-4 pers.
4-6 pers.
5-7 pers
6-8 pers.
8-10 pers.
10-12 pers.
12-14 pers.
14-16 pers.
16-18 pers.
I understand that javascript is sorting as followed :
""
1
10
11
2
3
4
5
6
7
8
9
But I would like to have it sorted from "" to 11 ("",1,2,3,4,5,6,7,8,9,10,11). Would appreciate some expertise here. Thanks.
HTML :
<select class="form-control" id="dessertservingID" data-value="10" name="dessertservingID" required="">
<option value="">** Please choose</option>
<option value="7">10-12 pers.</option>
<option value="8">12-14 pers.</option>
<option value="9">14-16 pers.</option>
<option selected="" value="10">16-18 pers.</option>
<option value="1">2-3 pers.</option>
<option value="11">20-24 pers.</option>
<option value="2">3-4 pers.</option>
<option value="3">4-6 pers.</option>
<option value="4">5-7 pers.</option>
<option value="5">6-8 pers.</option>
<option value="6">8-10 pers.</option>
</select>
Javascript :
$(function() {
var options = $('#dessertservingID option');
options.sort(function(a, b) {
if (a.value > b.value) {
return 1;
}
else if (a.value < b.value) {
return -1;
}
else {
return 0;
}
})
$("#dessertservingID").empty().append(options);
// Vive la France!
$('#dessertservingID option[value=""]').insertAfter($('#dessertservingID option:first'));
});
Upvotes: 0
Views: 138
Reputation: 50759
Use:
options.sort(function(a, b) {
return a.value-b.value;
})
Instead, to sort your numbers, there is no need for if statements. This will implicitly cast your values to numbers and calculate the difference.
See working example below:
$(function() {
var options = $('#dessertservingID option');
options.sort(function(a, b) {
return a.value-b.value;
})
$("#dessertservingID").empty().append(options);
$('#dessertservingID option[value=""]').insertAfter($('#dessertservingID option:first'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="form-control" id="dessertservingID" data-value="10" name="dessertservingID" required="">
<option value="">** Please choose</option>
<option value="7">10-12 pers.</option>
<option value="8">12-14 pers.</option>
<option value="9">14-16 pers.</option>
<option selected="" value="10">16-18 pers.</option>
<option value="1">2-3 pers.</option>
<option value="11">20-24 pers.</option>
<option value="2">3-4 pers.</option>
<option value="3">4-6 pers.</option>
<option value="4">5-7 pers.</option>
<option value="5">6-8 pers.</option>
<option value="6">8-10 pers.</option>
</select>
Upvotes: 0
Reputation: 1372
Try parsing option.value into an integer using parseInt before comparing the values:
$(function() {
var options = $('#dessertservingID option');
options.sort(function(a, b) {
let aValue = parseInt(a.value);
let bValue = parseInt(b.value);
aValue = isNaN(aValue) ? -1 : aValue;
bValue = isNaN(bValue) ? -1 : bValue;
return aValue - bValue;
})
Using parseInt forces proper numeric comparison instead of comparing the keycode values of the strings. The isNaN check is for the blank value, and setting the value to -1 if the parsed integer is NaN, ensures that it is the first returned value.
Upvotes: 0
Reputation: 29002
You can use parseInt
to get the numeric value of the string. It will try to get any numeric values from the beginning of the string until it encounters a non-numeric value. In your case, that is what you want - you will get 20
out of "20-24"
:
$(function() {
var options = $('#dessertservingID option');
options.sort(function(a, b) {
//parse the values
var valueA = parseInt(a.value);
var valueB = parseInt(b.value);
if (valueA > valueB) {
return 1;
} else if (valueA < valueB) {
return -1;
} else {
return 0;
}
})
$("#dessertservingID").empty().append(options);
$('#dessertservingID option[value=""]').insertAfter($('#dessertservingID option:first'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="form-control" id="dessertservingID" data-value="10" name="dessertservingID" required="">
<option value="">** Please choose</option>
<option value="7">10-12 pers.</option>
<option value="8">12-14 pers.</option>
<option value="9">14-16 pers.</option>
<option selected="" value="10">16-18 pers.</option>
<option value="1">2-3 pers.</option>
<option value="11">20-24 pers.</option>
<option value="2">3-4 pers.</option>
<option value="3">4-6 pers.</option>
<option value="4">5-7 pers.</option>
<option value="5">6-8 pers.</option>
<option value="6">8-10 pers.</option>
</select>
Upvotes: 0
Reputation: 337580
The problem is because you're comparing the value
properties as strings. Convert them to integers using parseInt()
first.
Also note that you can simplify your sort()
logic by simply subtracting one value from the other:
$(function() {
var $options = $('#dessertservingID option');
$options.sort(function(a, b) {
return parseInt(a.value, 10) - parseInt(b.value, 10);
})
$("#dessertservingID").empty().append($options);
$('#dessertservingID option[value=""]').insertAfter($('#dessertservingID option:first'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="form-control" id="dessertservingID" data-value="10" name="dessertservingID" required="">
<option value="">** Please choose</option>
<option value="7">10-12 pers.</option>
<option value="8">12-14 pers.</option>
<option value="9">14-16 pers.</option>
<option selected="" value="10">16-18 pers.</option>
<option value="1">2-3 pers.</option>
<option value="11">20-24 pers.</option>
<option value="2">3-4 pers.</option>
<option value="3">4-6 pers.</option>
<option value="4">5-7 pers.</option>
<option value="5">6-8 pers.</option>
<option value="6">8-10 pers.</option>
</select>
Upvotes: 2