There is a good example of this topic on Handle Events in Lightning Web Components trailhead which discusses the same use case as you have here (and answers both your questions).
The idea is to chain the events up the hierarchy. So basically you will need to handle the event being propagated in every component and then pass it on up in the hierarhcy.
Below excerpt and the image from the linked trailhead module describes this in detail :
Events Up, Properties Down
In a complex component (one that contains several parent and child components) we recommend you propagate the event up through the component hierarchy, so parent components can respond to child events. If you have other child components (not the one firing the event) you can pass a property down to those children in response to the event.
(Image Source: Handle Events in Lightning Web Components)
Update : Passing event from grand-child to grand-parent
Lets say we have a LWC component structure as follows.
We can pass event values between grand-child and grand-parent or the top most root component as follows.
Use bubbles : true
to pass values up the component hierarchy. And use composed : true
if you want to expose the event outside the shadow root.
grandChild.js
const sampleEvent = new CustomEvent('search', { bubbles : true, detail: { foo : 'bar' }, composed : true });
this.dispatchEvent(sampleEvent);
Note: If an event uses this configuration bubbles:true
& composed:true
, the event type becomes part of the component’s public API. It also forces the consuming component and all of its ancestors to include the event as part of their APIs.
This way, we don't have to handle this event in the parent component , Instead in grand parent we can handle it as follows
grandParent.html
<c-parent onsearch={handleSearch}></c-parent>
grandParent.js
handleSearch = (event) => {
console.log(event.detail);
}
For more details , refer - LWC Events Propagation
Best Answer
It's stated at very bottom of the documentation page (emphasis mine)
HTML:
JS:
Since it's called when the input loses focus too, if you want to handle only the "clear" action you need the if on
target.value.length
.