0

I am trying to sort option alphabetically

My Html is

<select id="myOpt">
    <option value="" selected data-default>Select Name</option>
    <option value="3">John Snow</option>
    <option value="34">Arya Stark</option>
    <option value="54">Sansa Stark</option>
    <option value="4">Hound</option>
</select>

js

var options = $("#myOpt option");                           
options.detach().sort(function(a,b) {               
    var at = $(a).text();
    var bt = $(b).text();         
    return (at > bt)?1:((at < bt)?-1:0);            
});
options.appendTo("#myOpt");

it sorts option correctly but now instead of selected option it shows last option. My question is how to show selected option instead of last option and can it be done by another client side method? since for big list it making page slow

1
  • Hello @Richerd Can you please add the code of html after sorting... Commented Apr 23, 2019 at 5:07

4 Answers 4

2

Try this,

var options = $("#myOpt option");  
var selectedVal = '';                         
options.detach().sort(function(a,b) {               
    var at = $(a).text();
    var bt = $(b).text();   
    if($(a).attr('selected') || $(b).attr('selected')){
        selectedVal = $(a).attr('selected') ? $(a).val() : $(b).val();
        return false;    
    }
    return (at > bt)?1:((at < bt)?-1:0);            
});
options.appendTo("#myOpt");
$('#myOpt').val(selectedVal);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
    <option value="" selected data-default>Select Name</option>
    <option value="3">John Snow</option>
    <option value="34">Arya Stark</option>
    <option value="54">Sansa Stark</option>
    <option value="4">Hound</option>
</select>

Sign up to request clarification or add additional context in comments.

Comments

2

Don't select the 1st option to sort. var options = $("#myOpt option:not(:eq(0))");

You may use web workers to avoid browser frize if this a big list. also, you can put it inside setTimeout to push it in event loop

$(function() {
  var options = $("#myOpt option:not(:eq(0))");
  options.detach().sort(function(a, b) {
    var be = $(b);
    var ae = $(a);

    if (be.attr('selected')) {
      selectedVal = be.val();
      return 1;
    }
    if (ae.attr('selected')) {
      selectedVal = ae.val();
      return -1;
    }

    var at = ae.text();
    var bt = be.text();
    return (at > bt) ? 1 : ((at < bt) ? -1 : 0);
  });
  options.appendTo("#myOpt");
  $("#myOpt").val(selectedVal);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
  <option value="" selected data-default>Select Name</option>
  <option value="3">John Snow</option>
  <option value="34">Arya Stark</option>
  <option value="54">Sansa Stark</option>
  <option value="4">Hound</option>
</select>

Comments

1

$(function() {
  var options = $("#myOpt option");
  options.detach().sort(function(a, b) {
    var be = $(b);
    var ae = $(a);

    if (be.attr('selected')) {
      selectedVal = be.val();
      return 1;
    }
    if (ae.attr('selected')) {
      selectedVal = ae.val();
      return -1;
    }

    var at = ae.text();
    var bt = be.text();
    return (at > bt) ? 1 : ((at < bt) ? -1 : 0);
  });
  options.appendTo("#myOpt");
  $("#myOpt").val(selectedVal);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
  <option value="" selected data-default>Select Name</option>
  <option value="3">John Snow</option>
  <option value="34">Arya Stark</option>
  <option value="54">Sansa Stark</option>
  <option value="4">Hound</option>
</select>

1 Comment

what if a option has a different selected value ? is there any option to show selected option by "SELECTED" tag instead ?
1

To do the sort using native JavaScript may actually give you somewhat more readable code, while taking advantage of operations (like shift/unshift) that jQuery does not implement.

The selection issue is occurring because an option detached from it's parent select cannot be selected - so you need to either select the first option again.

document.addEventListener("DOMContentLoaded", function() {
    var options = $("#myOpt option").detach()
    options = $.makeArray(options);
    var first = options.shift();
    options.sort( (a,b) => a.text.localeCompare(b.text) );
    options.unshift(first);
    $("#myOpt").append(options);
    $("#myOpt option").eq(0).prop("selected", true)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
    <option value="" selected data-default>Select Name</option>
    <option value="3">John Snow</option>
    <option value="34">Arya Stark</option>
    <option value="54">Sansa Stark</option>
    <option value="4">Hound</option>
</select>

You may want to simply just leave the selected element alone and just detach/sort the others, which ends up being quite a bit simpler:

document.addEventListener("DOMContentLoaded", function() {
    var options = $("#myOpt option").not('[value=""]').detach();
    options.sort( (a,b) => a.text.localeCompare(b.text) );
    $("#myOpt").append(options);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
    <option value="" selected data-default>Select Name</option>
    <option value="3">John Snow</option>
    <option value="34">Arya Stark</option>
    <option value="54">Sansa Stark</option>
    <option value="4">Hound</option>
</select>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.