Reputation: 23783
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
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
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
Reputation: 101614
Attribute selectors Is what you're looking for I believe.
Something like $+('element[attribute="value"]')
See also:
*=
anywhere^=
starts with$=
ends with~=
contains wordUpvotes: 1
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
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