marcq
marcq

Reputation: 483

Sort option values ASC

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

Answers (4)

Nick Parsons
Nick Parsons

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

asleepysamurai
asleepysamurai

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

VLAZ
VLAZ

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

Rory McCrossan
Rory McCrossan

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

Related Questions