0

I have a project where I need to set the select options in alphabetical order. Here's my HTML code:

<select id=”carmakes”>
    <option value="Volvo">Volvo</option>
    <option value="Mercedes">Mercedes</option>
    <option value="Audi">Audi</option>
    <option value="Saab">Saab</option>
</select>

And here is my script:

function alphabeticalOrder() {
    let value = document.getElementsByTagName("select")[0];
    for (let i = 0; i < value.children.length - 1; i++) {
        if (value.children[i].innerHTML < value.children[i + 1].innerHTML) {
            let temp = value.children[i].innerHTML;
            value.children[i].innerHTML = value.children[i + 1].innerHTML;
            value.children[i + 1].innerHTML = temp;
        }
    }
    return value;
}

I've tried using sort but I couldn't seem to get it to work.

Scoots
  • 3,048
  • 2
  • 21
  • 33
reiko1997
  • 21
  • 6
  • Looks like this is the same as your request. https://stackoverflow.com/a/23908505/12981969 – Reece Casey Feb 28 '20 at 22:20
  • You're just updating the innerHTML with this method, the `value` attribute will remain unchanged which will likely result in some semantic errors – Jon Warren Feb 28 '20 at 22:21
  • Just curious... do you have the ability to sort the options before they are generated?... this would be more ideal if possible. – scunliffe Feb 28 '20 at 22:22
  • @scunliffe Since it's not ideal to generate them in HTML first, I guess it's okay. – reiko1997 Feb 28 '20 at 22:49

1 Answers1

1

As scunliffe mentioned, it's best to start with the values in JS rather than in HTML in this case. Try this:

const makes = [
  'Volvo',
  'Mercedes',
  'Audi',
  'Saab'
];

const sortedMakes = makes.sort((a,b) => {
  if (a === b)
    return 0;
  if (a < b)
    return -1;
  return 1;
});

const selectEl = document.getElementById('carmakes');

for(const make of sortedMakes) {
  const newOpt = document.createElement('option');
  newOpt.value = make;
  newOpt.innerHTML = make;
  selectEl.appendChild(newOpt);
}
<select id="carmakes"></select>

If you must sort it with the values starting in HTML, you can do it like this:

const selectEl = document.getElementById('carmakes');
const makes = Array.from(selectEl.getElementsByTagName('option'))
  .map(el => el.innerText);

const sortedMakes = makes.sort((a,b) => {
  if (a === b)
    return 0;
  if (a < b)
    return -1;
  return 1;
});

while(selectEl.firstChild) {
  selectEl.firstChild.remove();
}

for(const make of sortedMakes) {
  const newOpt = document.createElement('option');
  newOpt.value = make;
  newOpt.innerHTML = make;
  selectEl.appendChild(newOpt);
}
<select id="carmakes">
  <option value="Volvo">Volvo</option>
  <option value="Mercedes">Mercedes</option>
  <option value="Audi">Audi</option>
  <option value="Saab">Saab</option>
</select>
stjns
  • 1,420
  • 13
  • 16
  • Thank you for this, is there no other way to sort options that are generated from HTML rather than in JS? – reiko1997 Feb 28 '20 at 22:46
  • The sorting will always happen in JS. HTML is static. It is possible to start with the values in HTML and sort them in JS, but that is not ideal if it can be avoided. – stjns Feb 28 '20 at 22:47