CF_HoneyBadger
CF_HoneyBadger

Reputation: 3009

jQuery select option contains AND not contains text

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

Answers (3)

Carsten Massmann
Carsten Massmann

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

Amit Gupta
Amit Gupta

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

T.J. Crowder
T.J. Crowder

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

Related Questions