skip to Main Content

From this select:

<select>
    <option disabled>Value 1</option>
    <option disabled>Value 2</option>
    <option>Value 3</option>
</select>

How I can mark the last item which is not disabled as selected?

Example of what I want to make is here:

$('button').click(function() {
    $('select option').attr('disabled', true);
    
    $('select option').each(function() {
        var currFormat = this.value;
        
        if(currFormat == '300x300' || currFormat == '400x400') {
            $(this).prop('disabled', false);
        }
    });
    
    $('select option:not(:disabled):last').prop('selected', true).change();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.min.js"></script>
<select>
    <option>100x100</option>
    <option>200x200</option>
    <option>300x300</option>
    <option>400x400</option>
    <option>500x500</option>
</select>

<button>Select only the 300x300 and 400x400</button>

If I click on the button in Safari, the first item is still selected whereas the 400×400 item should be selected.

Thanks.

2

Answers


  1. It’s 2023 and you definitely do not need jQuery for this.

    Use element properties instead of manipulating attributes dynamically. This appears to keep Safari happy.

    const allowed = new Set(["300x300", "400x400"]);
    
    const options = Array.from(document.querySelectorAll("option"));
    
    document.querySelector("button").addEventListener("click", (e) => {
      options.forEach((option) => {
        option.disabled = !allowed.has(option.value);
      });
      const lastEnabled = options.findLast(({ disabled }) => !disabled);
      if (lastEnabled) {
        lastEnabled.selected = true;
      }
    });
    <select>
        <option>100x100</option>
        <option>200x200</option>
        <option>300x300</option>
        <option>400x400</option>
        <option>500x500</option>
    </select>
    
    <button type="button">Select only the 300x300 and 400x400</button>

    jQuery answer

    const allowed = new Set(["300x300", "400x400"]);
    
    const options = $("option");
    
    $("button").on("click", () => {
      options.prop("disabled", function() {
        return !allowed.has(this.value);
      });
      options.filter(":not(:disabled)").last().prop("selected", true);
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.min.js"></script>
    <select>
        <option>100x100</option>
        <option>200x200</option>
        <option>300x300</option>
        <option>400x400</option>
        <option>500x500</option>
    </select>
    
    <button type="button">Select only the 300x300 and 400x400</button>
    Login or Signup to reply.
  2. No need for jQuery here; a simple path query is sufficient:

    console.log(document.querySelector('#foo option:not([disabled])'))
    <select id="foo">
        <option disabled>Value 1</option>
        <option disabled>Value 2</option>
        <option>Value 3</option>
    </select>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search