MegaMatt
MegaMatt

Reputation: 23783

jQuery: Select all 'select' elements with certain val()

Does anyone know of an easy way, using jQuery, to select all <select> elements whose val() attribute yields a certain value?

I'm trying to do some validation logic and would like to just select all those elements with a single selector, then apply a warning class to each of their parents. This I know how to do once I select all the elements, but I didn't see a selector that handles this case.

Am I going to have to select all of the <select> elements into a selector, then iterate through them and check each of their values? I was hoping there would be a simpler way.

Thanks.

Upvotes: 9

Views: 33053

Answers (5)

Jim Berg
Jim Berg

Reputation: 659

You can create a change event that puts the value in a custom attribute on the select element whenever the value changes. You can then use a simple selector to find all of the select elements that have that value. For example:

$("select").on("change", function (e) {
    var $select = $(e.currentTarget);
    $select.attr("select-value", $select.val());
});

And then you can do this:

var $matches = $("select[select-value='" + searchVal + "']");

$matches will have all of your matching selects.

This is a lot easier than having to iterate through elements. Remember to set select-value to the initial value when rendering the page so you don't need to trigger a change event for each select so the select-value is set.

Upvotes: 0

bobince
bobince

Reputation: 536715

Why doesn't select[value=x] work? Well firstly because <select> doesn't actually have a value attribute. There is not a single value of a select box: there may be no selected options (there shouldn't normally be, but there can be in at least IE), and, in a <select multiple>, there can be any number of selected options.

Even input[value=x] doesn't work, even though <input> does have a value attribute. Well, it does work, it just doesn't do what you think. It fetches the value of the value="..." attribute in the HTML, not the current value you have entered into the form. The value="..." attribute actually corresponds to the defaultValue property and not value.

Similarly, option[value=x][selected] doesn't work because it is checking the <option selected> attribute from the HTML source (selected attribute -> defaultSelected property) and not the current selectedness of the option (selected property not attribute) - which might have changed since the page was loaded.

Except in IE, which gets the value, selected etc form attributes wrong.

Except (again): Tesserex's example may seem to work, and the reason for that is that that it's using a non-standard jQuery-specific selector, :has. This causes the native querySelectorAll methods of modern browsers to fail, and consequently jQuery falls back to its own (native JavaScript, slow) selector engine instead. This selector engine has a bug where it confuses properties for attributes, allowing [value=x] to do what you expected, and not fail like it should! (Update: this is probably no longer the case in newer jQuery versions.)

Summary: form field state checking and selectors don't mix. Apart from these issues, you also have to worry about escaping issues - for example, what if the value you want to test against contains quotes or square brackets?

So instead, yes, you should check it manually. For example using a filter:

$('select').filter(function() {
    return $(this).val()==='the target value';
}).parent().addClass('warning');

(There is a value property in HTML5 and supported by modern browsers, that when you read it gives you the value of the first selected <option>. jQuery's val() is safe to use here because it provides the same method of getting the first selected option even on browsers that don't support this.)

Upvotes: 23

Brad Christie
Brad Christie

Reputation: 101614

Attribute selectors Is what you're looking for I believe.

Something like $+('element[attribute="value"]')

See also:

Upvotes: 1

Tesserex
Tesserex

Reputation: 17314

The existing answers don't work on select tags, but I found something that does. Ask for a select that has a selected option.

$("select:has(option[value=blah]:selected)")

Upvotes: 11

Sheavi
Sheavi

Reputation: 250

You can use :

$("select[value=X]");

where X is the value against which you want to check the select's value.

Upvotes: 1

Related Questions