4

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.

Lazlow
  • 41
  • 3
  • Add a class to the `select`s you want to act on, then use `each` to go over each of them. You probably want to set a variable for each `select` and use `find` to get the options, rather than using a selector. – Heretic Monkey Apr 05 '19 at 15:44
  • What is providing the 12 flavors? Usually you would want to sort the data before it makes it to the display... – Jarvis Apr 05 '19 at 15:44
  • Possible duplicate of [Sorting options elements alphabetically using jQuery](https://stackoverflow.com/questions/12073270/sorting-options-elements-alphabetically-using-jquery) – Heretic Monkey Apr 05 '19 at 15:45
  • @Jarvis It's a separate app I use on the store which doesn't provide the option to sort it. – Lazlow Apr 05 '19 at 15:48
  • @HereticMonkey I cannot add a class/do not know how to add a class to them unfortunately. – Lazlow Apr 05 '19 at 15:49
  • In the HTML, after ` – Heretic Monkey Apr 05 '19 at 15:51
  • @HereticMonkey I don't believe I have access to those files, it is supplied by the app and if I can access it then I am unsure where. – Lazlow Apr 05 '19 at 15:57
  • Each of the selectors is within its own div class, can I sort through those instead? – Lazlow Apr 05 '19 at 15:57
  • You should do some research into [jQuery selectors](http://api.jquery.com/category/selectors/) and how they work. I don't really have the time (nor is SO built for) the back and forth for teaching. – Heretic Monkey Apr 05 '19 at 16:08
  • @HereticMonkey Thanks for the resource, I wasn't asking with the intention of having one to one help, I just wanted to check if I was missing something painfully obvious in my existing solution. – Lazlow Apr 05 '19 at 16:13

1 Answers1

1

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>
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100