90

For this dropdownlist in HTML:

<select id="countries">
<option value="1">Country</option>
</select>

I would like to open the list (the same as left-clicking on it). Is this possible using JavaScript (or more specifically jQuery)?

Jon Tackabury
  • 47,710
  • 52
  • 130
  • 168
  • 1
    possible duplicate of [How can you programmatically tell an HTML SELECT to drop down (for example, due to mouseover)?](http://stackoverflow.com/questions/249192/how-can-you-programmatically-tell-an-html-select-to-drop-down-for-example-due) – Sam Hasler Oct 19 '12 at 09:22
  • 5
    Can anyone explain why this is so impossible? – SpaceBeers Apr 25 '14 at 21:12
  • checkout http://api.jqueryui.com/selectmenu/#method-open – Hayden Thring Aug 14 '17 at 11:30
  • Possible duplicate of [How can you programmatically tell an HTML SELECT to drop down (for example, due to mouseover)?](https://stackoverflow.com/questions/249192/how-can-you-programmatically-tell-an-html-select-to-drop-down-for-example-due) – toesslab Dec 03 '18 at 21:12

14 Answers14

74

I was trying to find the same thing and got disappointed. I ended up changing the attribute size for the select box so it appears to open

$('#countries').attr('size',6);

and then when you're finished

$('#countries').attr('size',1);
CommentLuv
  • 1,079
  • 1
  • 9
  • 14
  • 12
    adding `size` attribute to dropdown actually converts dropdown to Listbox..thus it expands.. – Mayank Pathak Aug 31 '12 at 06:24
  • Great solution. You just have to deal with the fact that the listbox takes up more space on the page (rather than expanding over the content like a dropdown) and, thus, pushes content down. – zkent Oct 28 '14 at 19:32
  • For those who can only imagine what it looks like, the appearance is a multi-select box after using this approach (but not multi-selectable) which I personally think is more stable than open up the dropdown. – Siwei Dec 23 '14 at 22:15
  • 2
    This technically works, but 1) you now have an ugly scroll bar down the side, and 2) the z-index is fixed to the original select, so it doesn't quite act like a popup pull-down either. – BoB3K May 17 '16 at 16:34
  • Thank you for this...I've spent 2 hours trying various popovers etc to alert users they have to choose something. Nothing was working well...this is a subtle but firm reminder. And it works (unlike flaky other solutions). – 11teenth Aug 29 '17 at 17:32
18

You can easily simulate a click on an element, but a click on a <select> won’t open up the dropdown.

Using multiple selects can be problematic. Perhaps you should consider radio buttons inside a container element which you can expand and contract as needed.

ieure
  • 2,381
  • 1
  • 16
  • 16
15

I've come across the same problem and I have a solution. A function called ExpandSelect() that emulates mouse clicking on "select" element, it does so by creating an another <select> element that is absolutely posioned and have multiple options visible at once by setting the size attribute. Tested in all major browsers: Chrome, Opera, Firefox, Internet Explorer. Explanation of how it works, along with the code here:

Edit (link was broken).

I've created a project at Google Code, go for the code there:

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

Screenshots

There is a little difference in GUI when emulating click, but it does not really matter, see it for yourself:

When mouse clicking:

MouseClicking
(source: googlecode.com)

When emulating click:

EmulatingClicking
(source: googlecode.com)

More screenshots on project's website, link above.

Community
  • 1
  • 1
Czarek Tomczak
  • 20,079
  • 5
  • 49
  • 56
10

This should cover it:

 var event;
 event = document.createEvent('MouseEvents');
 event.initMouseEvent('mousedown', true, true, window);
 countries.dispatchEvent(event); //we use countries as it's referred to by ID - but this could be any JS element var

This could be bound for example to a keypress event, so when the element has focus the user can type and it will expand automatically...

--Context--

  modal.find("select").not("[readonly]").on("keypress", function(e) {

     if (e.keyCode == 13) {
         e.preventDefault();
         return false;
     }
     var event;
     event = document.createEvent('MouseEvents');
     event.initMouseEvent('mousedown', true, true, window);
     this.dispatchEvent(event);
 });
Stuart.Sklinar
  • 3,683
  • 4
  • 35
  • 89
  • worked for me! every other answer suggested that there is *no* way to trigger a select yet you found one, are there any drawbacks to this approach? – kittyminky Aug 24 '15 at 00:57
  • Yup - it interferes with tabbing events (I Think!), It depends on your needs - but it worked as expected - but didn't fit our other needs. – Stuart.Sklinar Aug 24 '15 at 11:35
  • Worked for me. If calling from a different event handler remember to get the dom element out -- `$('#select_element').get(0).dispatchEvent(event);` – BoB3K May 17 '16 at 16:45
  • this doesn't work for me. running on Chrome 56.0.2924 on OSX – ekkis Feb 17 '17 at 02:11
  • 2
    this doesn't work for me. Looked promising though. – user3335999 Nov 13 '20 at 02:28
  • This technique is not valid anymore. Didn't work on Chrome 113.0.5672.126 – mdikici May 25 '23 at 12:23
8

This is spruced up from the answers just above and uses the length/number of options to conform to how many options there actually are.

Hope this helps somebody get the results they need!

    function openDropdown(elementId) {
        function down() {
            var pos = $(this).offset(); // remember position
            var len = $(this).find("option").length;
                if(len > 20) {
                    len = 20;
                }

            $(this).css("position", "absolute");
            $(this).css("zIndex", 9999);
            $(this).offset(pos);   // reset position
            $(this).attr("size", len); // open dropdown
            $(this).unbind("focus", down);
            $(this).focus();
        }
        function up() {
            $(this).css("position", "static");
            $(this).attr("size", "1");  // close dropdown
            $(this).unbind("change", up);
            $(this).focus();
        }
        $("#" + elementId).focus(down).blur(up).focus();
    }
Chris K
  • 81
  • 1
  • 1
7

Simple an easy way.

function down(what) {
  pos = $(what).offset();  // remember position
  $(what).css("position","absolute");
  $(what).offset(pos);   // reset position
  $(what).attr("size","10"); // open dropdown
}

function up(what) {
$(what).css("position","static");
$(what).attr("size","1");  // close dropdown
}

Now you can call your DropDown just like this

<select onfocus="down(this)" onblur="up(this)">

Works perfect for me.

Maybe better, because you have no problems with the position of the other elemts on the page.

function down(was) {
a = $(was).clone().attr('id','down_man').attr('disabled',true).insertAfter(was);
$(was).css("position","absolute").attr("size","10");
}

function up(was) {
$('#down_man').remove();
$(was).css("position","static");
$(was).attr("size","1");
}

Change the ID to a fix value mybe not smart but i hope you see the idee.

mrperfect
  • 71
  • 1
  • 2
4

It is not possible for javascript to "click" on an element (u can trigger the attached onclick event, but you can't literally click it)

To view all the items in the list, make the list a multiple list and increase its size, like such:

<select id="countries" multiple="multiple" size="10">
<option value="1">Country</option>
</select>
Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
  • Adds a scrollbar after 4 items in IE6, 7 & 8b2 and Opera 9.62. Adds a scrollbar after 10 items in Safari for Windows and Google Chrome. – Grant Wagner Dec 11 '08 at 19:01
2

I tried using mrperfect's answer and i had a couple glitches. With a couple small changes, I was able to get it to work for me. I just changed it so that it would only do it once. Once you exit dropdown, it would go back to the regular method of dropdowns.

function down() {
    var pos = $(this).offset(); // remember position
    $(this).css("position", "absolute");
    $(this).offset(pos);   // reset position
    $(this).attr("size", "15"); // open dropdown
    $(this).unbind("focus", down);
}
function up() {
    $(this).css("position", "static");
    $(this).attr("size", "1");  // close dropdown
    $(this).unbind("change", up);
}
function openDropdown(elementId) {
    $('#' + elementId).focus(down).blur(up).focus();
}
colinbashbash
  • 996
  • 2
  • 9
  • 19
2

One thing that this doesn't answer is what happens when you click on one of the options in the select list after you have done your size = n and made it absolute positioning.

Because the blur event makes it size = 1 and changes it back to how it looks, you should have something like this as well

$("option").click(function(){
    $(this).parent().blur();
});

Also, if you're having issues with the absolute positioned select list showing behind other elements, just put a

z-index: 100;

or something like that in the style of the select.

vipergtsrz
  • 1,061
  • 1
  • 12
  • 17
2

Super simple:

var state = false;
$("a").click(function () {
    state = !state;
    $("select").prop("size", state ? $("option").length : 1);
});
yckart
  • 32,460
  • 9
  • 122
  • 129
  • 1
    that's not the same as opening it. when a listbox is at the bottom of the page, if I open it, it opens upwards. if I change the size of it, it "opens" downwards, below where I can click. no good – ekkis Feb 17 '17 at 02:06
  • @ekkis The explained behaviour can vary on different devices and browsers. I have tested my proposed solution with Firefox, Google Chrome and Opera on desktop and Safari on mobile, where it works as expected. The scroll-jump could easily fixed by saving/restoring the scroll-offset on open/close or maybe by using [`scrollIntoView`](https://developer.mozilla.org/docs/Web/API/Element/scrollIntoView) on the ` – yckart Feb 18 '17 at 04:45
2

No you can't.

You can change the size to make it larger... similar to Dreas idea, but it is the size you need to change.

<select id="countries" size="6">
  <option value="1">Country 1</option>
  <option value="2">Country 2</option>
  <option value="3">Country 3</option>
  <option value="4">Country 4</option>
  <option value="5">Country 5</option>
  <option value="6">Country 6</option>
</select>
scunliffe
  • 62,582
  • 25
  • 126
  • 161
1

As has been stated, you can't programmatically open a <select> using JavaScript.

However, you could write your own <select> managing the entire look and feel yourself. Something like what you see for the autocomplete search terms on Google or Yahoo! or the Search for Location box at The Weather Network.

I found one for jQuery here. I have no idea whether it would meet your needs, but even if it doesn't completely meet your needs, it should be possible to modify it so it would open as the result of some other action or event. This one actually looks more promising.

Grant Wagner
  • 25,263
  • 7
  • 54
  • 64
0

i just added

select = $('#' + id);
length = $('#' + id + ' > option').length;
if (length > 20)
    length = 20;
select.attr('size', length);
select.css('position', 'absolute');
select.focus();

and add into the select

onchange="$(this).removeAttr('size');"
onblur="$(this).removeAttr('size');"

to make the same appearance like the classic one (overlap the rest of html)

Emmanuel
  • 11
  • 2
-1

Maybe late, but this is how i solved it: http://jsfiddle.net/KqsK2/18/

$(document).ready(function() {
  fixSelect(document.getElementsByTagName("select"));
                      });                       

   function fixSelect(selectList)
            {
            for (var i = 0; i != selectList.length; i++)
              {

                 setActions(selectList[i]);
              }
            }


   function setActions(select)
            {
               $(select).click(function() {
                   if (select.getElementsByTagName("option").length == 1)
                        {
                          active(select);
                        }
                      });
                $(select).focus(function() {
                       active(select);
                       });
                $(select).blur(function() {
                       inaktiv(select);
                       });
                $(select).keypress(function(e) {
                      if (e.which == 13) {

                      inaktiv(select);
                          }
                       });
                  var optionList = select.getElementsByTagName("option");

                  for (var i = 0; i != optionList.length; i++)
                           {
                                setActionOnOption(optionList[i], select);
                           }
      }

  function setActionOnOption(option, select)
      {
                    $(option).click(function() {
                                inaktiv(select);
                        });
      }

  function active(select)
      {
          var temp = $('<select/>');
              $('<option />', {value: 1,text:$(select).find(':selected').text()}).appendTo(temp);
               $(temp).insertBefore($(select));

              $(select).attr('size', select.getElementsByTagName('option').length);
              $(select).css('position', 'absolute');
              $(select).css('margin-top', '-6px');
              $(select).css({boxShadow: '2px 3px 4px #888888'});



                        }

        function inaktiv(select)
                   {
                 if($(select).parent().children('select').length!=1)
                     {
                                             select.parentNode.removeChild($(select).parent().children('select').get(0));
                                }
                $(select).attr('size', 1);
                $(select).css('position', 'static');
                $(select).css({boxShadow: ''});
                $(select).css('margin-top', '0px');

                  }
Johan Nordli
  • 1,220
  • 3
  • 13
  • 26