I am using lit-html library to render the data into the form.
The program should auto fill the product name upon inputting the product number. I have written the code but I am unable to auto fill the product name field. For the product name, I have used static dummy data within my JavaScript code.
Is there a way to do this using only web components or using library 'lit-html'?
Below you can find my code
import {html, render} from 'lit-html'
class MyApp extends HTMLElement {
constructor() {
super()
this.attachShadow({mode: 'open'});
const forms = () => {
const productNum = new Array();
const productName = new Array();
productNum[0] = 123;
productName[0] = 'Paper';
productNum [1] = 500;
productName[1] = 'Laptop';
function details(products) {
if (products > 50) {
for (let i = 0; i < productNum.length; i++) {
if (products == productNum[i]) {
this.info.product.value = productName[i]
} else {
this.info.product.value = ''
}
}
}
}
return html` <form name = 'info'>
<input type="text" name="product" onkeyup="${details(parseInt(this.value, 10))}" maxlength=3>ProductNum
<input type="text" name="productName" onkeyup="">ProductName
</form>`
}
const template = html`
${forms()}`
render(template, this.shadowRoot)
}
}
window.customElements.define('my-app', MyApp)
Objective: (auto)Fill related Form fields with (product) data
One (native) component way is to let the FORM handle the querying for product data
Communicate productinfo with Events
That way there is no dependency between components (other than an EventName),
and you can have as many related inputs as you need.
Relevant Custom Element code:
<my-form>
<my-input name="productkey"></my-input>
<my-input name="productname"></my-input>
</my-form>
customElements.define("my-form", class extends HTMLElement {
constructor() {
super();
let products = productDatabaseMap();
this.addEventListener("getProduct", evt => {
let detail={
product: products[evt.detail.value],
input: evt.target // input that requested product details
};
dispatchEvent(this, "setProduct", detail);
});
}
})
customElements.define("my-input", class extends HTMLElement {
constructor() {
super();
let input = this.appendChild(document.createElement('input'));
let name = input.placeholder = this.getAttribute('name');
this.onkeyup = evt => dispatchEvent(input, "getProduct", evt.target);
this.closest("my-form").addEventListener("setProduct", evt => {
let product = evt.detail.product;
if (product instanceof Product) input.value = product[name];
else if (evt.detail.input !== input) input.value = '';
});
}
})
Working JSFiddle: https://jsfiddle.net/WebComponents/L2dcruoh/
If you wrap
<my-input>
in a shadowRoot you need more boilerplate code and be awareevent.detail
then needscomposed:true
to make it cross shadow boundaries. Andevent.target
will reference the (last) component it came from... not theinput
field that triggered that event