I’m writing a custom <select>
element using native DOM (no Polymer).
I’m trying to use my element with a <label>
element and correctly trigger click events to my element when the <label>
is clicked, i.e.:
<label>
My Select:
<my-select placeholder="Please select one">...</my-select>
</label>
or
<label for='mySelect1'>My Select:</label>
<my-select id='mySelect1' placeholder="Please select one">...</my-select>
However, this behavior doesn’t seem to work out of the box, even if I add a tabindex
to make it focusable.
Here’s a stripped down version of the code and a JSFiddle with some basic debugging:
var MySelectOptionProto = Object.create(HTMLElement.prototype);
document.registerElement('my-select-option', {
prototype: MySelectOptionProto
});
var MySelectProto = Object.create(HTMLElement.prototype);
MySelectProto.createdCallback = function() {
if (!this.getAttribute('tabindex')) {
this.setAttribute('tabindex', 0);
}
this.placeholder = document.createElement('span');
this.placeholder.className = 'my-select-placeholder';
this.appendChild(this.placeholder);
var selected = this.querySelector('my-select-option[selected]');
this.placeholder.textContent = selected
? selected.textContent
: (this.getAttribute('placeholder') || '');
};
document.registerElement('my-select', {
prototype: MySelectProto
});
Only the phrasing content elements can be targeted by <label>
.
So you'll have to manage the focus action by yourself if you want to use a non-standard (autonomous custom) element.
Instead you can choose to define a Customized built-in element that will extend the <select>
element, as in the following example:
https://jsfiddle.net/h56692ee/4/
var MySelectProto = Object.create( HTMLSelectElement.prototype )
//...
document.registerElement('my-select', { prototype: MySelectProto, extends: "select" } )
You'll need to use the is
attribute notation for HTML:
<label>
My Select:
<select is="my-select" placeholder="Please select one">
<option>...</option>
</select>
</label>