I am trying to wrap an input field inside a custom element.
The custom element DOM looks like this:
<custom-element>
<div class="fancy-wrapper">
<input value="4">
</div>
<custom-element>
While the element should work like this:
<custom-input id="test"></custom-input>
<script>
let test = document.getElementById('test')
console.log(test.value); // should return 4 (value of inner input)
test.onkeydown = function(e){
console.log(e.target.value); // should the new value of the inner input
};
</script>
Is there any way to get the <custom-input>
attributes redirected to the <input>
attributes inside it, without connecting everything by hand?
No, it is no different than having one DIV and another child DIV
You have to make the connection between the CustomElement and content yourself.
One way is to define a Get/Set function on your Custom-Element that fetches the value of a child input
Instead of manually declaring Get/Set You can ofcourse loop any child element and assign on the CustomElement with defineProperty or Proxies
Example below creates 2 INPUT fields and a this.input
array:
<number-and-range>
<input type="number"> // this.input[0]
<input type="range"> // this.input[1]
</number-and-range>
And connects (GET/SET) <number-and.range>.value
to this.input[0]
customElements.define('number-and-range', class extends HTMLElement {
get value() {
return this.input[0].value;
}
set value(val) {
//input validation should go here
this.input[0].value = val;
console.clear();
console.log('new value:',val);
}
connectedCallback() {
this.input = ['number', 'range'] //create [0] and [1] values in array
.map((type, idx) => Object.assign(
this.appendChild(document.createElement('input')), {
type,
min: 20,
max: 50,
oninput: _ => this.value = this.input[~~!idx].value = this.input[idx].value //toggle [0] and [1]
}));
this.value = 42;//default value
}
});
let el=document.querySelector('number-and-range');
console.log(el.value);
el.value=99;
<body>
<h3>Custom Element : Connected INPUT and Range slider</h3>
Please enter a number between 20 and 50, or use the range slider
<p>
<number-and-range></number-and-range>
</p>
</body>