Lazlow
Lazlow

Reputation: 41

Sorting through multiple select options efficiently

I'm new to JQuery, programming in general, but have been experimenting with it for the last couple of days in relation so sorting multiple select option dropdowns alphabetically. I have come up with a solution but I am sure there is a far more efficient way to write this but at this time it is beyond me. How to I go through each select without calling them directly? It needs to happen on page load without user interaction.

window.addEventListener("load", function () {
    $("select[name='properties[Flavour 1]']").html($("select[name='properties[Flavour 1]'] option").sort(function (a, b) {
        return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
    }))
    $("select[name='properties[Flavour 1]']").get(0).selectedIndex = 0;
  //Flavour 2
    $("select[name='properties[Flavour 2]']").html($("select[name='properties[Flavour 2]'] option").sort(function (a, b) {
        return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
    }))
    $("select[name='properties[Flavour 2]']").get(0).selectedIndex = 0;
  //Flavour 3
    $("select[name='properties[Flavour 3]']").html($("select[name='properties[Flavour 3]'] option").sort(function (a, b) {
        return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
    }))
    $("select[name='properties[Flavour 3]']").get(0).selectedIndex = 0;
}, false);

This continues on until Flavour 12 but you get the idea of how it is set out.

Upvotes: 4

Views: 341

Answers (1)

Mark Schultheiss
Mark Schultheiss

Reputation: 34168

This should give you a generic solution, I added a wrapper so I could get the count and not hard code the number or pollute the global DOM. I added a document level alternative but remove it if you can.

NOTE: After thinking this over a bit I noted your "Flavours" spelling and concluded that this may need some localization SO, I modified the sort to use that instead. return a.text.localeCompare(b.text);

I also added classes to show those were retained as well as any selected default adjustment to retain the prior value.

For the second example I compacted all that down to a shorter jQuery version, expand that to see it there.

More here on the sorting specifics: What is the most efficient way to sort an Html Select's Options by value, while preserving the currently selected item?

window.addEventListener("load", function() {
  let myflavours = $('#flavours').find('select[name^="properties[Flavour"]').length;
  //alternate
  let myflavoursNotAsGood = $(document).find('select[name^="properties[Flavour"]').length;
  console.log(myflavoursNotAsGood);
  for (let f = 1; f <= myflavours; f++) {
    let sel = $("select[name='properties[Flavour " + f + "]']");
    let v = sel.val();
    let opts = sel.find("option").sort(function(a, b) {
      return a.text.localeCompare(b.text);
    });
    sel.html(opts).val(v);
  }
}, false);
.water {
  color: blue;
}

.drink {
  color: orange;
}

.yuk {
  color: brown;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="flavours">
  <select name='properties[Flavour 1]'>
    <option>Cheese</option>
    <option>Apple</option>
    <option selected="selected">Cotton Candy</option>
    <option>Blueberry</option>
    <option class="yuk">Rotten Eggs</option>
    <option class="water">Swamp Water</option>
    <option class="water">Swamp Scum</option>
  </select>
  <select name='properties[Flavour 2]'>
    <option>Cheese</option>
    <option>Apple Smoked Bacon</option>
    <option selected="selected">Blueberry</option>
    <option class="yuk">Rotten Eggs</option>
    <option class="drink">Bier</option>
    <option>Bacon</option>
    <option class="water">Swamp Water</option>
    <option class="water">Swamp Scum</option>
  </select>
</div>

Second example built differently than yours a bit.

$(function() {
  $('#flavours').find('select[name^="properties[Flavour"]')
    .each(function(index, element) {
      let v = element.value;
      $(this).html($(this).find("option").sort(function(a, b) {
        return a.text.localeCompare(b.text);
      })).val(v);
    });
});
.water {
  color: blue;
}

.drink {
  color: orange;
}

.yuk {
  color: brown;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="flavours">
  <select name='properties[Flavour 1]'>
    <option>Cheese</option>
    <option>Apple</option>
    <option selected="selected">Cotton Candy</option>
    <option>Blueberry</option>
    <option class="yuk">Rotten Eggs</option>
    <option class="water">Swamp Water</option>
    <option class="water">Swamp Scum</option>
  </select>
  <select name='properties[Flavour 2]'>
    <option>Cheese</option>
    <option>Apple Smoked Bacon</option>
    <option selected="selected">Blueberry</option>
    <option class="yuk">Rotten Eggs</option>
    <option class="drink">Bier</option>
    <option>Bacon</option>
    <option class="water">Swamp Water</option>
    <option class="water">Swamp Scum</option>
  </select>
</div>

Upvotes: 1

Related Questions