How can you programmatically tell an HTML SELECT to drop down (for example, due to mouseover)?

JavascriptHtml

Javascript Problem Overview


How can you programmatically tell an HTML select to drop down (for example, due to mouseover)?

Javascript Solutions


Solution 1 - Javascript

This used to actually be possible with HTML+Javascript, despite everywhere else people say it is not, but it was deprecated later on and does not work now.

However, this only worked in Chrome. Read more if you're interested.


According to W3C Working Draft for HTML5, Section 3.2.5.1.7. Interactive Content:

> Certain elements in HTML have an activation behavior, which means that the user can activate them. This triggers a sequence of events dependent on the activation mechanism [...] for instance using keyboard or voice input, or through mouse clicks.

> When the user triggers an element with a defined activation behavior in a manner other than clicking it, the default action of the interaction event must be to run synthetic click activation steps on the element.

<select> being an Interactive Content, I believed that it is possible to programatically display its <option>s. After a few hours of playing around, I discovered that using document.createEvent() and .dispatchEvent() works.

That said, demo time. Here is a working Fiddle.


HTML:

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" onclick="runThis()">Show dropdown items</button>​

Javascript:

// <select> element displays its options on mousedown, not click.
showDropdown = function (element) {
    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);
};

// This isn't magic.
window.runThis = function () { 
    var dropdown = document.getElementById('dropdown');
    showDropdown(dropdown);
};

If anyone finds a way to do the same but not in Chrome, please feel free to modify this fiddle. ​

Solution 2 - Javascript

Xavier Ho's answer is covering how to solve the issue in most browsers currently out there. But, it's good practice 'not to dispatch/modify' events by JavaScript anymore. (Like, mousedown in this case)

From version 53+, Google Chrome will not perform default action for un-trusted events. Such as events created or modified by script, or dispatched via dispatchEvent method. This change is for aligning with Firefox and IE which I think already not performing the action.

For testing purposes, Fiddle provided Xavier's answer won't work in chrome 53+. (I don't test it FF and IE).

Links for reference:

https://www.chromestatus.com/features/5718803933560832 https://www.chromestatus.com/features/6461137440735232

And initMouseEvent is also deprecated

Solution 3 - Javascript

This is the closest I could get, change the size of the element onmouseover, and restore the size onmouseout:

<select onMouseOut="this.size=1;" onMouseOver="this.size=this.length;">
  <option>1</option>
  <option>2</option>
  <option>3</option>
  <option>4</option>
  <option>5</option>
</select>

Solution 4 - Javascript

I have this same problem and the easier way I found to solve this was with HTML and CSS.

First, make you <select> transparent (opacity: 0;). Then, place your button over the <select>. The click over the button will be caught by the <select> component.

select{
  opacity: 0;
  position: absolute;
}

<select>
  <option>option 1</option>
  <option>option 2</option>
  <option>option 3</option>
</select>
<button>click</button>

Solution 5 - Javascript

You can't do this with a HTML select tag, but you can do it with JavaScript and HTML. There are variety of existing controls that do this - for instance, the "suggest" list attached to the SO "interesting/ignored tag" entry, or Gmail's lookup for email adresses.

There are many JavaScript+HTML controls that provide this capability--look for autocomplete controls for ideas.

See this link for the Autocomplete control...http://ajaxcontroltoolkit.codeplex.com/

Solution 6 - Javascript

I think this is no longer possible in Chrome.

It seems version 53 of chrome disables this functionality as stated by Asim K T.

> According to the spec > http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events > > Trusted Events should not fire the default action (except click > event).

They have however enabled it in webview, but I have not tested this.

> We have found that some webviews are using fastclick inside them and > due to a risk of breakage we are going to allow mousedown on selects > even if they are untrusted.

And in this discussion the idea to let developers open a dropdown programatically is abandoned.

Solution 7 - Javascript

If any one is still looking for this :

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" >Show dropdown items</button>

Javascript:

var is_visible=false; 

$(document).ready(function(){

    $('#fire').click(function (e) { 
    var element = document.getElementById('dropdown');

    
    if(is_visible){is_visible=false; return;}
    is_visible = true;
    
    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);
    
    /* can be added for i.e. compatiblity.
      optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
    */
    e.stopPropagation();
    return false;
});

    
$(document).click(function(){is_visible=false; });
});

Update:

One till there is no perfect solution to this problem, But you can try to avoid this scenario. Why do you want to do this. i was wondering for a solution few months back to make a select plugin for mobile devices

https://github.com/HemantNegi/jquery.sumoselect

Finally ended up with masking the custom div (or any other element) with a transparent select element, so that it can directly interacts with user.

Solution 8 - Javascript

Here's the best way I found. NOTE It only works with IE on Windows and your web would probably need to be in a secure zone - because we access the shell. The trick is that ALT-Down Arrow is a shortcut key to open a select drop down.

<button id="optionsButton" style="position:absolute;top:10px;left:10px;height:22px;width:100px;z-index:10" onclick="doClick()">OPTIONS</button>
<select id="optionsSelect" style="position:absolute;top:10px;left:10px;height:20px;width:100px;z-index:9">
    <option>ABC</option>
    <option>DEF</option>
    <option>GHI</option>
    <option>JKL</option>
</select>
<script type="text/javascript">
   function doClick() {
       optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
   }
</script>

Solution 9 - Javascript

Stop thinking that one thing is impossible, nothing is impossible to do, when you want to do.

Use this expand JS function created by a guy.

http://code.google.com/p/expandselect/

Include this JS and just call that passing the param as your select id, like that:

ExpandSelect(MySelect)

Solution 10 - Javascript

If anyone is still looking for this, This is how I solved it.

This is a solution based on the fact that the selection looks like it is expanded when the size in increased. We can increase size to make it look expanded. And reduce to make it seem closed. This way we can handle most use-cases by just having focus and blur listeners.

Select element needs to be absolutely positioned because increasing size will increase vertical height of element. If you have elements below, they will be pushed down if this is not done.

I have a wrapper code, that wraps the element and provides open and close methods.

Check this fiddle for usage: https://jsfiddle.net/10ar2ebd/16/

var SelectionWrapper = function(element, maxSize, selectCb) {

  var preventDefault = function(e) {
    e.preventDefault();
    e.stopPropagation();
  }

  var isOpen = false;

  var open = function() {
    if (!isOpen) {
      element.size = maxSize;
      // Remove prevent default so that user will be able to select the option
      // Check why we prevent it in the first place below
      element.removeEventListener('mousedown', preventDefault);
			// We focus so that we can close on blur.
      element.focus();
      isOpen = true;
    }
  };

  var close = function() {
    if (isOpen) {
      element.size = 1;
      // Prevent default so that the default select box open behaviour is muted.
      element.addEventListener('mousedown', preventDefault);
      isOpen = false;
    }
  };

	// For the reason above
  element.addEventListener('mousedown', preventDefault);

	// So that clicking elsewhere closes the box
  element.addEventListener('blur', close);

	// Toggle when click
  element.addEventListener('click', function(e) {
    if (isOpen) {
      close();
      // Call ballback if present
      if(selectCb) {
				selectCb(element.value);
			}
    } else {
      open();
    }
  });


  return {
    open: open,
	  close: close
  };
};

// Usage
var selectionWrapper = SelectionWrapper(document.getElementById("select_element"), 7, function(value) {
  var para = document.createElement("DIV");
  para.textContent = "Selected option: " + value;
  document.getElementById("result").appendChild(para);
});

document.getElementById("trigger").addEventListener('click', function() {
  selectionWrapper.open();
});

Solution 11 - Javascript

Here is the solution on https://jsfiddle.net/NickU/ahLy83mk/50/

It uses size="x" to open the dropdown while maintaining the dropdown and parent positions. The code also uses CSS styles to hide the right scroll area when it is not needed. I modified the code I found on stackoverflow, fixed the problems and added styling.

HTML:

<div>DIV example: <select id="dropdownDiv">
    <option value="Alpha">Alpha</option>
    <option value="Beta">Beta</option>
    <option value="Gamma">Gamma</option>
    </select>
</div>

<table id='tab1'>
<tr><td>Empty Cell</td></tr>
<tr><td> <select id="dropdown1">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
    </select>
</td>
<tr><td><select id="dropdown2">
<option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="15">1</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option></select>
</td></tr>
<tr><td>Empty Cell</td></tr></table>
<br><button id="fire" type="button" onclick="openDropdown('dropdownDiv', this)" >Show dropdownDiv items</button>
<button id="fire" type="button" onclick="openDropdown('dropdown1', this)" >Show dropdown1 items</button>
<button id="fire" type="button" onclick="openDropdown('dropdown2', this)" >Show dropdown2 items</button>

JavaScript:

  var lastClosedElem = null;
  var maxItemsInDropDown = 12;
  function openDropdown(elementId, opener)
  {
     if (lastClosedElem !== null && lastClosedElem === opener)
     {
            lastClosedElem = null;
            return;
     }
     lastClosedElem = opener;
     
     function down()
      {
          var $this = $(this);

          var td = $this.closest('td,div');
          if (td && td.length > 0)
              td.height(td.height());

          var pos = $this.offset();
          var len = $this.find("option").length;
          if (len > 1 && len < maxItemsInDropDown)
          {
              $this.addClass('no-scroll');
              $this.addClass('noArrow');
          }
          else if (len > maxItemsInDropDown)
          {
              len = maxItemsInDropDown;
          }

          $this.css("position", "absolute");

          var _zIndex = $this.css("zIndex");
          if (!_zIndex)
              _zIndex = 'auto';
          $this.attr("_zIndex", _zIndex);
          $this.css("zIndex", 9999);

          $this.attr("size", len); // open dropdown
          $this.unbind("focus", down);
          $this.focus();
      }

      var up = function()
      {
          var $this = $(this);
          $this.css("position", "static");
          $this.attr("size", "1");
          $this.removeClass('no-scroll');
          $this.removeClass('noArrow');

          var _zIndex = $this.attr("zIndex");
          if (_zIndex)
          {
              $this.css("zIndex", _zIndex);
          }
          $this.unbind("blur", up);
          $this.unbind("click", upClick);
          $this.focus();
      }

      function upClick(e)
      {
          up.call(this);
          lastClosedElem = null;
      }

      $("#" + elementId).focus(down).blur(up).click(upClick).trigger('focus');
  }

CSS:

.no-scroll { cursor: pointer;}
.no-scroll::-webkit-scrollbar {display:none;}
.no-scroll::-moz-scrollbar {display:none;}
.no-scroll::-o-scrollbar {display:none;}
.no-scroll::-google-ms-scrollbar {display:none;}
.no-scroll::-khtml-scrollbar {display:none;}


.noArrow {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-left: 3px;
    padding-right: 3px;
}


/* Cosmetic styles */
#tab1 tbody tr:nth-child(even) > td, div
{   background: linear-gradient( 180deg, #efefef 1%, #eeeeee 15%, #e2e2e2 85%); 
}
        
#tab1 tbody tr td
{   padding: 4px; 
}
        
#tab1
{   border: 1px solid silver; 
}

Solution 12 - Javascript

I may be wrong, but I don't believe that is possible with the default select box. You could do something with JS & CSS that achieves the desired result, but not (to my knowledge) the vanilla SELECT.

Solution 13 - Javascript

This is not exactly what you asked for, but I like this solution for its simplicity. In most cases where I am wanting to initiate a dropdown, it is because I'm validating that the user has actually made a selection. I change the size of the dropdown and focus it, which nicely highlights what they've skipped:

$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();

Solution 14 - Javascript

Opening an "HTML select" is possible through some workarounds mentioned in this question and similar ones. However a cleaner way of doing this is to add a select library to your project like "select2" or "chosen". For instance, opening a select2 programmatically would be as easy as:

$('#target-select').select2('open');

Solution 15 - Javascript

I don't know if I'm fully understanding the question, but to open a dropdown, this simple approach worked for me.

You have an element:

<span onclick="openDropdown();">Open dropdown</span>

You have a dropdown:

<select class="dropdown">
    <option value="A">Value A</option>
    <option value="B">Value B</option>
    <option value="C">Value C</option>
</select>

And with JavaScript you can do the following:

document.querySelector('.dropdown').focus();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCorey TragerView Question on Stackoverflow
Solution 1 - JavascriptXavier HoView Answer on Stackoverflow
Solution 2 - JavascriptAsim K TView Answer on Stackoverflow
Solution 3 - JavascriptChristian C. SalvadóView Answer on Stackoverflow
Solution 4 - JavascriptRafael UmbelinoView Answer on Stackoverflow
Solution 5 - Javascriptrp.View Answer on Stackoverflow
Solution 6 - JavascriptUnderstaticView Answer on Stackoverflow
Solution 7 - JavascriptHemant_NegiView Answer on Stackoverflow
Solution 8 - JavascriptsproketboyView Answer on Stackoverflow
Solution 9 - JavascriptPaulo Roberto RosaView Answer on Stackoverflow
Solution 10 - JavascriptCaleb HillaryView Answer on Stackoverflow
Solution 11 - JavascriptMykola UspalenkoView Answer on Stackoverflow
Solution 12 - Javascriptuser1921View Answer on Stackoverflow
Solution 13 - JavascriptRob3CView Answer on Stackoverflow
Solution 14 - JavascriptKasra EbrahimiView Answer on Stackoverflow
Solution 15 - JavascriptJeroen BellemansView Answer on Stackoverflow