HTMLSelectElement add ability to show option list programmatically


#1

Problem:

The ability to open a HTMLSelectElement's option list from javascript doesn't exist. Some of the solutions used currently with Chrome won't work in the future due to planned trusted event processing.

An example of a current solution that works in Chrome is:

showDropdown = function (element) {
    var event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);
};

showDropdown(document.getElementById('dropdown'));

This solution relies on the fact that Chrome currently allows untrusted events to execute the default action. The default action for the HTMLSelectElement for mousedown is to open the option list.

According to the UI Event specification untrusted actions should not execute the default action. Chromium’s bug number is 334015.

Solution:

Since this is not consistent across all browsers I would like to propose that we add a open() method to the HTMLSelectElement that will open the option list when called.
interface HTMLSelectElement : HTMLElement {
      void               open();
      void               close();
    };

This method would run the focusing-steps open the select option list. If the element is inert it would do nothing.

Use Cases:

One possible of use of this functionality is an annotated tutorial that progressively instructs the user to fill out the form values as it executes. It may overlay instructions and indicate the user to select the correct option shown.

Auto-converting links to the HTML Living Standard to use multipage locations
#2

I’ve seen developers ask about doing this a bunch (eg. this stackoverflow thread), and it seems reasonable to me that it should be possible. I wish I had some concrete examples of websites relying on this in Chrome at the moment, but that won’t be easy to find until we break their workaround.


#3

I prefer an open attribute just like in <dialog>:

<select open>
 <option value="1">1</option>
</select>

So that in my markup I can also decide that its open.

In my JS:

select.open; // true
select.open = false; // closes it and removes open attribute

Also a close() method:

select.close(); // closes it and removes open attribute

The close() method exist in the <dialog> element as well, I guess for preference.

Also whenever the <select> is opened by mouse/keyboard that open attribute is added, so that you can check if open. (Not sure what’d be the use but just be best, just in case there is a use for detecting if open)


#4

Please link to the mutipage spec page rather than locations in the one-page spec, for those of us on slow connections, phones, or low-memory Chromebooks.


Auto-converting links to the HTML Living Standard to use multipage locations
#5

If we’re fully pedantic, it ought to be this, since apparently that’s preferred. I guess the stability of the individual subpages isn’t guaranteed?


#6

@dtapuska Could you add a “Use cases” section (with one or more examples) to your original post?


#7

My first impression was that this was a good idea but then I ran into some problems…

The <dialog> specification does do mirroring of the open variable; although I’m not sure if it would really be great here. It works well because the open variable is basically an attribute selector for “display: none” on the dialog element. Sometimes UAs work with native controls for these that aren’t represented in the HTML view like <dialog> is and this can create a synchronization problem. ie; The reading the value of open may not really represent exactly what the author of the page really wants.

I tried implementing this in Chrome and I ran into a few problems.

<select id='first' open>
  <option>1</option>
</select>
<select id='second' open>
<option>2</option>
</select>

<script>
document.getElementById('first').open // should be true
document.getElementById('second').open // likely should be false; but may return true depending on timing of how the UA processes the second select
</script>
  • What happens with the values when they are removed from the DOM and added back to the DOM?
  • What happens when ‘multiple’ is added as an attribute or specified at the same time as open?
  • The open value may not reflect what is currently on the screen because it may not be synchronous. For example if we set two selects with open.

#8

Do you have a specific example that you’d like to see. I added a textual example; and I’m sure I can come up with others so I’m not really sure if what I described is what you wanted. Please let me know and I can revise if need be.


#9

@RickByers I remember seeing http://www.hbogo.com/activate use this behavior in Chrome.

0!==g.nsIphonePicker&&(d.isIphone()||d.isIpad()||d.isAndroid())?(e.$watch("iphoneSelectedItem",e.onClick),f.bind("click",function(b){if("SELECT"!==b.target.nodeName&&!e.disabled){var c=f.find("select");if(c.show(),a[0].createEvent){var b=a[0].createEvent("MouseEvents");b.initMouseEvent("mousedown",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),c[0].dispatchEvent(b)}else c.fireEvent&&c[0].fireEvent("onmousedown")}}

@dtapuska I’m not sure I understand the synchronicity issue. I don’t see an issue blocking us from making element.open = true synchronously open a select control. Browsers do seem to enforce a single control being opened at a time. So in your example, the first element would no longer have a value of open==true once the second element is parsed.


#10

@jacobrossi It’s really an implementation detail. I attempted to show/hide the popup when the HTMLSelectElement was attached/detached to the layout/render tree. The problem with that is that is inside a layout so I can’t manipulate the DOM during a layout. So what I would need to do is dispatch a show of the popup after the layout is done.

Depending on how I handled it if I just pushed it as an event to execute later then #9 shows a case where it is pathologically incorrect. If I inserted it as an event that occurs just after layout then it would likely work but would require some custom plumbing…

Perhaps I was attempting it incorrect; but I was recording how it might cause me issues if the “boolean open” was the desired approach wrt to this problem.


#11

Great, thanks for the concrete use case! That’s probably justification enough to keep Chrome from becoming spec-compliant on event default actions until we’ve shipped a replacement API.


#12

To resurrect this discourse. I’m considering abandoning this request due to the fact that:

  1. Other vendors don’t do this
  2. It isn’t clear what should happen with iframes for this proposal. We’ve thought about it and think that an iframe is able to annoy the user by requesting the focus to the iframe.

It might just be better to point people who want this behavior to implement the widget themselves. There are a number of examples: http://jsfiddle.net/BB3JK/47/ http://codepen.io/wallaceerick/pen/ctsCz