0

I have a select list that looks like this:

<select id="testSelect">
    <option value="option1" label="1">Option 1</option>
    <option value="option3" label="3">Option 3</option>
    <option value="option5" label="5">Option 5</option>
</select>​

I'm using the label to control the order in which the options should be displayed. The initial select list is in the correct order (despite missing items).

I would like to programatically add a new option to this select list. I found this question which provided me with a link to an excellent jquery select cheat sheet.

This cheat sheet provides the following code to add options at a specific index, which is similar to what I want to do:

$("#elementid option:eq(0)").after("<option value='4'>Some pears</option>"

However, I don't need to insert a new option after a specific index (because these items will be removed and re-added multiple times), I need to insert the option in the correct order based on the label value.

I tried two things:

$(function () {
   $("#testSelect option:eq(1)").after("<option value='option2' label='2'>Option 2</option>"); //Method A
    $("#testSelect option:label(1)").after("<option value='option2' label='2'>Option 2</option>"); //Method B
});​

Method A inserts the new item after the second item in the list, which makes my list look like: 1 3 2 5

Method B throws an exception: Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: label

However, even if Method B worked, I would still have an issue since the option with the label of 1 may not actually exist. What I'd really like to do is insert the new option in the correct place in the list (based on the label) regardless of whether or not specific option elements exist around it.

Any ideas how this could be done? jsfiddle

Community
  • 1
  • 1
Mansfield
  • 14,445
  • 18
  • 76
  • 112

2 Answers2

4

You need to use the [] for attributes selector. You can read about the available selectors here http://api.jquery.com/category/selectors/

$("#testSelect option[label=yourvalue]").after("<option value='option2' label='2'>Option 2</option>"); //Method B

So

$("#testSelect option[label=1]") // will grab <option value="option1" label="1">Option 1</option>

And the new option will be inserted after that element

You can sort the elements accordingly

$(function() {    
    $('#testSelect option')
          .add($("<option value='option7' label='7'>Option 7</option>"))
          .sort(function(a, b) {
                return a.label < b.label ? -1 : a.label > b.label ? 1 : -1;
          }).appendTo('#testSelect');
});​

http://jsfiddle.net/5ksh7/

wirey00
  • 33,517
  • 7
  • 54
  • 65
  • Ahh yes, that makes sense. But how will this work when a selected index doesn't exist? (second part of my question) Example: http://jsfiddle.net/Mansfield/mGgKK/2/ – Mansfield Dec 12 '12 at 16:24
  • @Mansfield let me work on the fiddle real quick and I'll update my answer with how you can do that. – wirey00 Dec 12 '12 at 16:29
  • I've accepted j08691's answer, but this was very helpful as well...+1 – Mansfield Dec 12 '12 at 16:34
2

How about this?

jsFiddle example

You can insert your new options anywhere and then just sort the options based on their label value.

$("#testSelect").append("<option value='option2' label='2'>Option 2</option>");

$("#testSelect option").sort(function(a, b) {
    if ($(a).attr('label') < $(b).attr('label')) return -1;
    if ($(a).attr('label') > $(b).attr('label')) return 1;
    return 0;
}).appendTo('#testSelect');​
j08691
  • 204,283
  • 31
  • 260
  • 272