5

I have a select menu and I need to dynamically select the option based on the text value of the option element. For example, my select looks like this:

<select id="names">
    <option value="">Please Select</option>
    <option value="1">John</option>
    <option value="2">Steve</option>
    <option value="3">Max</option>
</select>

If I have the string "Max", how can I get that the index of the option is 4 so I can dynamically set this as the selectedIndex with JavaScript?

No jQuery.

Unihedron
  • 10,902
  • 13
  • 62
  • 72
Zoolander
  • 2,293
  • 5
  • 27
  • 37

9 Answers9

5

Try this, it should find and then select the relevant option in the select box.

var searchtext = "max";
for (var i = 0; i < listbox.options.length; ++i) {
    if (listbox.options[i].text === searchtext) listbox.options[i].selected = true;
}
ipr101
  • 24,096
  • 8
  • 59
  • 61
5

http://jsfiddle.net/x8f7g/1/

You want to select the element, iterate over the array, find the text value, and return the index.

  • Don't use InnerHTML, it's slow and breaks and not standards compliant
  • Dont use innerText, simmilar reasons but not quite as serious
  • Do use a function so you can do it all over again.
  • Do select the child text node, and retreives the nodeValue, which is cross-browser friendly

Example:

function indexMatchingText(ele, text) {
    for (var i=0; i<ele.length;i++) {
        if (ele[i].childNodes[0].nodeValue === text){
            return i;
        }
    }
    return undefined;
}
Incognito
  • 20,537
  • 15
  • 80
  • 120
4

You could use this short function to do that:

function findIndexfromOptionName( select, optionName ) {
    let options = Array.from( select.options );
    return options.findIndex( (opt) => opt.label == optionName );
}

Arguments:

  • select: an HTMLSelect element
  • optionName: as a string

Explanation:
On the first line of the function body we retrieve the <select> options as an array using Array.from(). This allow us to use Array.prototype.findIndex() to return the index of the first option that match the provided name, if any or return -1 if there is no match.

Want some reasons to use it ?
It has a short implementation and the semantic is pretty clear. Also pure JS.

Darkosphere
  • 107
  • 8
  • You're implementation appears to be fine (elegant, you could even chain the calls to make a one-liner), but this is a **12 year old question** that already had **9 existing answers**. Does this really add anything new? – Jared Smith Feb 25 '23 at 14:21
  • 3
    Thought its a 12 year old question it was the first one to show up on google search engine that's why I decided to post an updated answer. Edit here is the search string used: _get the index of an – Darkosphere Feb 25 '23 at 14:24
  • Fair enough +1. Just an FYI though people *frequently* post plagarized (literal copy-paste of an existing answer), incorrect answers, and flat-out spam on old questions especially (no offense) users that haven't acquired a lot of rep on the site yet. It always raises a bit of a red flag when scrolling through the feed. I don't want to discourage you from doing it when it's needed but people may question it (like I did here). – Jared Smith Feb 25 '23 at 14:28
  • @JaredSmith it's the only answer not explicitly looping over the options, and I tried it because I find it the most elegant. I strongly encourage Darkosphere to try to improve old answers – Lante Dellarovere Mar 27 '23 at 17:42
  • @Lante Dellarovere glad to hear the answer was helpful. After all that's why we usually post them. :p – Darkosphere Apr 07 '23 at 14:58
3
var opts = document.getElementById("names").options;
for(var i = 0; i < opts.length; i++) {
    if(opts[i].innerText == "Max") {
        alert("found it at index " + i + " or number " + (i + 1));
        break;
    }
}

Demo.

karim79
  • 339,989
  • 67
  • 413
  • 406
1

The options property stores the options in a select menu - iterate over it and compare the contents.

var list = document.getElementById("names").options;

for(var i = 0; i<list.length; i++){
    if(list[i].text== "Max") { //Compare
        list[i].selected = true; //Select the option.
    }
}

JSFiddle: http://jsfiddle.net/cuTxu/2

Dennis
  • 32,200
  • 11
  • 64
  • 79
  • @Incognito Updated my answer. Is it really so bad that "assassinates" is a valid description? – Dennis Sep 20 '11 at 18:53
  • Absolutely, it's a non-standard thing that treats the DOM as if the object-model is raw-text to be altered all willy-nilly, it's not part of the spec either. Go see how bad it is performance wise for yourself on jsperf. – Incognito Sep 20 '11 at 18:55
  • @Incognito Good to know. I hadn't realized that it was not part of the standard. – Dennis Sep 20 '11 at 19:38
  • It's because of how the DOM works, MISE introduced innerHTML wayyyy back, anyone who uses it surrenders their right to badmouth IE6 :P. It's because once HTML is read by your browser as *objects* in memory, not a string that's parsed as html each time a change is made to the document. Browsers force it to work because of "backwards compatibility," and it leads to more problems and a slower experience for everyone. – Incognito Sep 20 '11 at 19:46
1

in PLAIN js

var sel, opts, opt, x, txt;
txt='Max';
sel=document.getElementById('names');
opts=sel.options;
for (x=0;x<opts.lenght;x++){
    if (opts[x].text === txt){
        opt=opts[x];
    }
}
Einacio
  • 3,502
  • 1
  • 17
  • 21
0

[edit - expanded to include non-jquery method]

I strongly recommend using jQuery for this since the solution is a one-liner:

jQuery('#names option:contains("Max")').val()

However, here's a pure JavaScript implementation anyway:

function findOption( select, matchMe ) {

  var

    // list of child options
    options = select.getElementsByTagName('option'),

    // iteration vars
    i = options.length,
    text,
    option;

  while (i--) {

    option = options[i];
    text = option.textContent || option.innerText || '';

    // (optional) add additional processing to text, such as trimming whitespace
    text = text.replace(/^\s+|\s+$/g);

    if (text === matchMe) {
      return option.getAttribute('value');
    }

  }

  return null;

}

Example usage:

alert(
  findOption(
    document.getElementsByTagName('select')[0],
    "Max"
  )
);

Alerts 3

jimbo
  • 11,004
  • 6
  • 29
  • 46
  • Thanks for the response, but it has to be plain JavaScript -- no jQuery! – Zoolander Sep 20 '11 at 18:36
  • 1
    I strongly recommend learning how to use plain JavaScript and becoming aware of what would make jQuery undesirable for something like this. – Incognito Sep 20 '11 at 19:28
0
var x = document.getElementById("names");
for(var i = 0; i<x.options.length; i++){
    if("Max" == x.options[i].text){
        doSomething();
        //maybe x.selectedIndex = i;
    }
}
Brian Colvin
  • 370
  • 1
  • 10
0

This should do the trick:

var options = document.getElementsByTagName('select')[0].children,
    i,
    l = options.length,
    index;

for(i = 0; i < l; i++){
  if(options[i].firstChild.nodeValue === 'Max'){index = i};
}

Please note that the index is zero based, what mean it is one less than you would expect.

topek
  • 18,609
  • 3
  • 35
  • 43