So, I’m creating my first web component and I’m struggling with the event handling side with elements within the shadow root.
The goal with this component is to display a list of results from an endpoint where the user types in an input field and then grab the text from the selected element and display it on the same input field.
The HTMl is this:
<div class="results">
<ul>
<li class="result-item"><i></i><span>Amalfiküste</span></li>
<li class="result-item"><i></i><span>Guatemala</span></li>
<li class="result-item"><i></i><span>Italien, Malta</span></li>
<li class="result-item"><i></i><span>Malaysia</span></li>
<li class="result-item"><i></i><span>Malediven</span></li>
<li class="result-item"><i></i><span>Mallorca</span></li>
<li class="result-item"><i></i><span>Malta</span></li>
</ul>
</div>
I then query the result-item:
let resultItem = document.querySelector('destination-search').shadowRoot.querySelectorAll('.result-item');
And the function to get the selected value into the input:
function selectTextIntoInput(resultItem, searchInput, shadowRoot) {
for (let i = 0; i < resultItem.length; i++) {
resultItem[i].addEventListener("click", function (event) {
searchInput.value = resultItem[i].innerText;
const destinationEvent = new CustomEvent('destination-search', {
detail: resultItem[i].innerText,
bubbles: true,
composed: true
});
shadowRoot.dispatchEvent(destinationEvent);
});
}
}
I’ve checked the console to see if I was querying the result-item fields and it’s working fine. The problem is clicking each one ,select the text into the input and dispatch it as a custom event to be used by another component.
How do we handle click events within shadow root elements?
2
Answers
You need to use composed option in the event, and also need to use arrow function
like this below updated code:-
Instead of
<li class="result-item"><i></i><span>Amalfiküste</span></li>
Make it a Web Component
<result-item>
And keep all (interaction) logic inside the Web Component