Reputation: 3009
I have a dropdown with options that look like this :
<select name="decision">
<option value="">** Select **</option>
<option value=0>No</option>
<option value=1>Yes*</option>
</select>
Depending on a prior user selection, either the "Yes" or "No" may have an asterisk next to the text.
I need to find a way to remove the asterisk from the end of either the Yes or No after the onChange event of another field.
My train of thought was to edit the text of options that contain "*" and DON'T contain "**" and remove the asterisk but I am doing something wrong and am not sure how to make this work.
$('[name=decision] option:contains("*"):not:contains("**")').text($.this.text().replace("*",""));
I figure I'm either
a) really close and am just missing something minor, or
b) doing something so horribly wrong that I need to switch career fields
Any help is appreciated.
Upvotes: 0
Views: 1667
Reputation: 28226
Or you can do it like this (assuming that ** Select **
will always be the first option):
$('select option:not(:first)').text((_,o)=>o.replace("*",""))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name="decision">
<option value="">** Select **</option>
<option value=0>No</option>
<option value=1>Yes*</option>
</select>
<select name="choice">
<option value="">** Select again **</option>
<option value=0>No*</option>
<option value=1>Yes</option>
</select>
Upvotes: 1
Reputation: 252
If the select values 1,0 does not have any significance then you can change the value of select
<select name="decision">
<option value="">** Select **</option>
<option value='No'>No</option>
<option value='Yes'>Yes*</option>
</select>
and get selected value instead of selected text
$("#decision").val();
Upvotes: 0
Reputation: 1075209
I think the answer to your specific question is:
$('[name=decision] option:contains("*"):not(:contains("**"))').text((_, text) => text.replace("*",""));
Live Example:
$("[name=decision]").on("change", function() {
$('[name=decision] option:contains("*"):not(:contains("**"))').text((_, text) => text.replace("*",""));
});
<select name="decision">
<option value="">** Select **</option>
<option value=0>No</option>
<option value=1>Yes*</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The two changes there are:
:not(:contains("**"))
instead of :not:contains("**")
Passing a function to text
so text
can call it, although you could also use
const option = $('[name=decision] option:contains("*"):not(:contains("**"))');
option.text(option.text().replace("*",""));
That just removes the *
, which is what you seemed to be working on, it doesn't add the *
to the newly-selected option.
For me it would be simpler with a basic loop that does both:
$("[name=decision]").on("change", function() {
for (const option of this.options) {
if (!option.text.endsWith("**")) { // Or `if (option.index > 0) {`
option.text = option.text.replace("*", "");
if (option.selected) {
option.text += "*";
}
}
}
});
<select name="decision">
<option value="">** Select **</option>
<option value=0>No</option>
<option value=1>Yes*</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Or if you don't want to use for-of
because you need to support obsolete browsers:
// For obsolete browsers
$("[name=decision]").on("change", function() {
for (var n = 1; n < this.options.length; ++n) {
var option = this.options[n];
option.text = option.text.replace("*", "");
if (option.selected) {
option.text += "*";
}
}
});
<select name="decision">
<option value="">** Select **</option>
<option value=0>No</option>
<option value=1>Yes*</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 1