5

If I have this select box:

<select id="s" name="s">
<option value="0">-</option>
<option value="1">A</option>
<option value="2" selected>B</option>
<option value="3">C</option>
</select>

If I try to run $("#s").val("4"), the selection changes to "0". (See behavior here: http://jsfiddle.net/4NwN5/) How can I make it so that if I attempt to set the select box to a value that does not exist in the select box that nothing changes?

adam0101
  • 29,096
  • 21
  • 96
  • 174

3 Answers3

7

You can try this way:

var toSel = 3; // Say your value is this
if($("#s option[value=" + toSel +"]").length > 0) //Check if an option exist with that value
{
    $("#s").val(toSel); //Select the value
}

or Just use prop()

$("#s option[value='" + toSel +"']").prop('selected', true);

Demo

PSL
  • 123,204
  • 21
  • 253
  • 243
  • And if my option happens to have a value that is not valid in a jquery selector? Like a "["? – adam0101 Jun 14 '13 at 18:02
  • Is there some function to escape all special characters not valid in a jquery selector? – adam0101 Jun 14 '13 at 18:04
  • @adam0101 Yup we can apply regex and a utility function.. I will set up a fiddle. – PSL Jun 14 '13 at 18:09
  • @adam0101 No need to use regex see my answer update with the Demo. Just wrap the value in quotes and it will work. – PSL Jun 14 '13 at 18:11
  • @adam0101 Doesn't matter check this http://jsfiddle.net/nQwFy/. Worst case you want to apply regex check this answer http://stackoverflow.com/questions/2786538/need-to-escape-a-special-character-in-a-jquery-selector-string – PSL Jun 14 '13 at 18:15
  • 1
    @PSL was playing with your example and that made me clear out my doubt about `attr` vs `prop` +1 for that – exexzian Jun 14 '13 at 18:33
1
// grab the selected
var s = $("#s");

// cache the current selectedIndex
var idx = s[0].selectedIndex;

// set the value
s.val("4");

// If it was set to `0`, set it back to the original index
s[0].selectedIndex = s[0].selectedIndex || idx;

And you can roll this into a plugin:

jQuery.fn.selectVal = function (val) {
    return this.each(function () {
        if (this.nodeName === "SELECT") {
            var idx = this.selectedIndex;

            $(this).val(val);

            var newOpt = this.options[this.selectedIndex];

            if (newOpt.value !== ("" + val))
                this.selectedIndex = idx;
        }
    })
};

$("#s").selectVal(4);
  • When would s[0].selectedIndex ever be null? I'm not understanding the last line – adam0101 Jun 14 '13 at 18:11
  • @adam0101: It'll be `0` if it was set to the first option. Because `0` is falsey, it'll then use `idx`. –  Jun 14 '13 at 18:13
  • @adam0101: I updated the plugin so that it'll work when you want to set it to `0`. And FWIW, this is a very light-weight operation compared to doing a DOM selection based on the value. –  Jun 14 '13 at 18:23
  • I agree. Plus you're only doing one loop to set the value as opposed to a using a second loop to check for the existence of the value. – adam0101 Jun 14 '13 at 18:31
0

jsFiddle Demo

You would want to use a custom filter before you call jquery's val

$.fn.valScreen = function(value){
 if( this.is("select") && this.find("option[value="+value+"]").length != 0 )
  this.val(value);//call vanilla val
 return this;//return jQuery object for chaining
};

You could then use it:

$("#s").valScreen("4");
Travis J
  • 81,153
  • 41
  • 202
  • 273