I am trying to create a web component that is usable in a form element specifically, that has a name
, and a value
. I recognize that I can create a web component that extends
an HTMLInputElement
:
<input is="very-extended">
but I am trying to create an entirely new element.
When creating a regular web component, you can create it from the prototype of a regular HTMLElement
(HTMLElement.prototype
). Which leads me to assume that I can create a different element with the prototype of an HTMLInputElement
(HTMLInputElement.prototype
). You actually use that prototype when extending
the API of input elements, so why can't I use that prototype to create an entirely new element that works in a form?
If you look at the shadow dom of a regular input field:
you can see that there is a div inside of there. I understand that this HTMLInputElement
has methods and attributes, getters/setters, etc. So why is it that when I attempt to create my component, it fails to be part of the name, value pairs found in the form?
Here is an example of how I am trying to create this web component:
Please note that his should be tested in a browser that supports web components.
(function() {
var iconDoc = (document._currentScript || document.currentScript).ownerDocument;
var objectPrototype = Object.create(HTMLInputElement.prototype);
Object.defineProperty(objectPrototype, 'name', {
writable: true
});
Object.defineProperty(objectPrototype, 'value', {
writable: true
});
objectPrototype.createdCallback = function() {
var shadow = this.createShadowRoot();
var template = iconDoc.querySelector('#test');
shadow.appendChild(template.content.cloneNode(true));
};
document.registerElement('custom-input', {
prototype: objectPrototype
});
})();
console.log(
$('form').serialize()
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<template id="test">
<div>This is a special input</div>
</template>
<form>
<input name="regular" value="input">
<custom-input name="foo" value="bar"></custom-input>
</form>
Why is the name, value pair not found among the form, and how can I create a custom form element?
You can create your <custom-input>
custom element that will be interpreted by a form
, just by adding inside your template
a hidden input
element with the
name
and value
pair your want.
<template>
<input type="hidden" name="foo" value="defaultVal">
</template>
The default value
(and name
) can by updated by your custom element internal logic.
This hidden input
must not be inserted inside a Shadow DOM to be detected by the container form
.
(function() {
var iconDoc = (document._currentScript || document.currentScript).ownerDocument;
var objectPrototype = Object.create(HTMLInputElement.prototype);
objectPrototype.createdCallback = function() {
//var shadow = this.createShadowRoot();
var template = iconDoc.querySelector('#test');
this.appendChild(template.content.cloneNode(true));
};
document.registerElement('custom-input', {
prototype: objectPrototype
});
})();
console.log(
$('form').serialize()
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<template id="test">
<input type="hidden" name="foo" value="bar">
</template>
<form>
<input name="regular" value="input">
<custom-input name="foo" value="bar"></custom-input>
</form>