27

I have the following HTML code:

<select>
<option selected>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
</select>

How do I check if the <option>s of the <select> are displayed? For example, this is considered as the <option>s of the <select> are displayed:

Options of the select menu are displayed

And this is considered that the <option>s of the <select> are not displayed:

Options of the select menu are not displayed


I have tried this:

$("#myselect").on("click", function() {
    if ($("#myselect option").length == 0) {
        console.log("not displayed");
    } else {
        console.log("displayed");
    } 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="myselect">
<option selected>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
</select>

But the console logs "displayed" all the time.


So how can I achieve this?


EDIT 1:

The answers at How to check if an select element is still “open” / active with jquery does not work because when I click the select element to display the options then click it again, the options are not displayed even though the select is still focused.


EDIT 2:

Just in case I wasn't explicit enough, basically I want the console to log "displayed" or "not displayed" the user clicks on the select or the options

Community
  • 1
  • 1
chris97ong
  • 6,870
  • 7
  • 32
  • 52

9 Answers9

15

You can try listening on click, blur and key press event. I am just toggling a open variable to true or false on each of the event.

   // if menu is open then true, if closed then false
   // we start with false
   var open = false;
   // just a function to print out message
   function isOpen(){
       if(open)
          return "menu is open";
       else
          return "menu is closed";
   }
   // on each click toggle the "open" variable
   $("#myselect").on("click", function() {
         open = !open;
         console.log(isOpen());
   });
   // on each blur toggle the "open" variable
   // fire only if menu is already in "open" state
   $("#myselect").on("blur", function() {
         if(open){
            open = !open;
            console.log(isOpen());
         }
   });
   // on ESC key toggle the "open" variable only if menu is in "open" state
   $(document).keyup(function(e) {
       if (e.keyCode == 27) { 
         if(open){
            open = !open;
            console.log(isOpen());
         }
       }
   });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="myselect">
<option selected>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
</select>
Sami
  • 3,926
  • 1
  • 29
  • 42
  • Try clicking the `select`. This shows all the options and logs "menu is open". Click the `select` again. This hides all the options and the console logs "menu is close". Then click anywhere else that is not the `select`. Console logs "menu is open". Your answer just needs a quick fix, other than that it seems to be working well. – chris97ong Jun 09 '15 at 11:09
  • 1
    If you use click/blur that fix problem with checking whether select is open. But there is a keys, ESC, ENTER, SPACE. So on space pressed, you should set it as open, on esc closed, on enter closed as well (actually click will be fired so we don't need to handle this) – Rantiev Dec 21 '15 at 10:23
  • in Firefox Developer Edition 68.0b10, running the code snippet does not at all work as described. When the menu is closed and you click to open it, no event is fired. Nothing logged in console. It just alternates between "menu is open" and "menu is closed" each time the menu is closed. – stef Jun 20 '19 at 21:07
  • This will fail in earlier versions of Chrome, because of `Enter` key. Check out my implementation with a perfect example – Iglesias Leonardo Mar 30 '22 at 22:16
4

You can use change event in case of not displayed, and focus event for displayed

$("#myselect").on({
  "change": function() {
    $(this).blur();
  },
  'focus': function() {
    console.log("displayed");
  },
  "blur": function() {
    console.log("not displayed");
  },
  "keyup": function(e) {
    if (e.keyCode == 27)
      console.log("displayed");
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="myselect">
  <option selected>Test 1</option>
  <option>Test 2</option>
  <option>Test 3</option>
</select>
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
1

After reading, I´ve realized that Option tags are not "usual" DOM elements. Then, is not so easy to control it (instead you are checking click, blur, and combining other methods as we started trying before).

Now I´ve managed you finally found the solution in a mix of the first idea we had, then, i´ll just explain the other possible solutions you have and all the things I´ve learned about selects:

  • If you DON´t add a size attribute to the select, you will not be able to detect keypress at the time it´s open.

  • If you add a size attribute bigger than 1 to the select, it will detect keypress, but will loose it´s format and a list will appear.

  • If you try to use offset, and similar, to check wether the select is open, is also not working, as the option objects do not have offset functions... (they are not usuarl DOM objects)

  • Click/focus will also not be enough, as the focus remains in select after a "ESC" click.

Then, after all those things reviewed, I think it´s not possible to make it in a pure HTML way without doing a lot of click/blur controls like answered before.

Anyway, to clarify, there are lots of jquery librarys that will help you to simulate a select/option dropdown, and to control if it´s open.

I hope this answer will solve your Question. Check this functional fiddle I´ve prepared for you to show the jquery dropdown way:

$('#jq-dropdown-1').on('show', function(event, dropdownData) {
  console.log("SHOWN");
}).on('hide', function(event, dropdownData) {
  console.log("HIDDEN");
});
<link rel="stylesheet" href="https://rawgit.com/claviska/jquery-dropdown/master/jquery.dropdown.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://rawgit.com/claviska/jquery-dropdown/master/jquery.dropdown.min.js"></script>

<a href="#" data-jq-dropdown="#jq-dropdown-1">dropdown</a>
<div id="jq-dropdown-1" class="jq-dropdown jq-dropdown-tip">
  <ul class="jq-dropdown-menu">
    <li><a href="#1">Item 1</a>
    </li>
    <li><a href="#2">Item 2</a>
    </li>
    <li><a href="#3">Item 3</a>
    </li>
    <li class="jq-dropdown-divider"></li>
    <li><a href="#4">Item 4</a>
    </li>
    <li><a href="#5">Item 5</a>
    </li>
    <li><a href="#5">Item 6</a>
    </li>
  </ul>
</div>


<button id="clickme">click me</button>

Those are the docs I´ve read to understand it:

Community
  • 1
  • 1
1

Im suggesting you to use new jquery selectmenu which is providing selectmenu open event

$("#myselect").selectmenu({
  open: function(event, ui) {
    alert("opened");
  }
});
label {
  display: block;
}
select {
  width: 200px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<select id="myselect">
  <option selected>Test 1</option>
  <option>Test 2</option>
  <option>Test 3</option>
</select>

Ref : http://api.jqueryui.com/selectmenu/#event-open

Shafeeque
  • 2,039
  • 2
  • 13
  • 28
  • 1
    I am using a lot of plugins already and I do not wish to use another one... But anyway this a very straightforward answer – chris97ong Jun 09 '15 at 11:27
0

The following may be worth trying out if you want an easier attempt. Simply :focus on the element.

  var $mselect = window.jQuery("select");
  $mselect.focus(function () {
    console.log('select values should be visible');
  });
klewis
  • 7,459
  • 15
  • 58
  • 102
0

I used this code:

cnt = document.getElementById('your_select').childElementCount;

if (cnt == 0) {
  ...
}

There are no option elements in your_select element.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
-2

A practical example through ES6 would be to add a class to select when it is open and remove it when it is closed. Note that in earlier versions of Chrome, when you press spacebar and enter, the options also appear. But enter behaviour in other browsers are far different then Chrome.

const element = document.getElementById('docType');
setupSelect(element);

function setupSelect(element) {
    element.selectedIndex = -1;
    
    let clickedByMouse = false;

    element.onclick = () => {
        if (!element.value) {
            if (!clickedByMouse) {
                toogleSelectOptions(element);
            } else {
                clickedByMouse = false;
            }
        }
    }

    element.onmousedown = () => {
        if (!element.value) {
            clickedByMouse = true;
            toogleSelectOptions(element);
        }
    }

    element.onblur = () => {
        if (!element.value) {
            if (element.classList.contains('is-open')) {
                element.classList.remove('is-open');
            }
        }
    }

    element.onchange = () => {
        if (element.value) {
            if (!element.classList.contains('is-open')) {
                element.classList.add('is-open');
            }
        }
    }

    element.onkeydown = (e) => {
        if (e.keyCode == 32) {
            if (!element.value) {
                toogleSelectOptions(element);
            }
        } else if (e.keyCode == 13) {//Enter does not work in Firefox the same way as Chrome
            e.preventDefault();
        }
    }

    element.onkeyup = (e) => {
        if (e.keyCode == 27) {
            if (!element.value) {
                if (element.classList.contains('is-open')) {
                    element.classList.remove('is-open');
                }
            }
        }
    }
}

function toogleSelectOptions(element) {
    if (element.classList.contains('is-open')) {
        element.classList.remove('is-open');
    } else {
        element.classList.add('is-open');
    }
}
select.is-open{
  background-color:red;
}
<div class="floating">
  <select name="docType" id="docType">
      <option value="1">ID</option>
      <option value="2">Passport</option>
      <option value="3">Drivers license</option>
  </select>
  <label for="docType">Document Type</label>
</div>

You can add more functions to simplify this into a more readable code, and handle each separately.

If i get +10 votes, i'll post a full implementation of an inline floating label, like this one:

Material design menu

  • Once it turns red it remains red even after the drop down is closed in Edge Chromium using the mouse if you select an option. – NetMage Jul 12 '22 at 16:01
-3

Solution:

select is an input, it has a focus state, so when it's focused the list(options) will be displayed, when it's not the list of options will disappear. So:

$("#myselect").on("click", function() {
    if ($("#mySelect").is(":focus")) {
        console.log("displayed");
    } else {
        console.log("not displayed");
    } 
});

Hope that helps.

Fadi Obaji
  • 1,454
  • 4
  • 27
  • 57
-3

What about simple check when jquery is 1.6+

  if ($(".selector").is(":focus")){
      // do stuff
  }

or

$(".selector").on('focus', function() {
    // do stuff
});

It can do the trick.

Eryk Wróbel
  • 416
  • 1
  • 4
  • 11