I’ve honestly racked my brain on this for a couple days. I’m decently new to lit-element and web components in general.
Basically, I’m building a new component called <date-picker>
and it uses the Flatpickr plugin. This Date Picker component imports another component called <textfield>
. Inside of that component there is a wrapper(.date-picker) with an input field and an icon. I need to be able to access the wrapper so I can click the input field and icon to trigger the calendar popup. But no matter what I do, I can’t reach those the dom elements inside the component. I’ve tried accessing them using this.shadowRoot.querySelector('.date-picker')
along with the light dom document.querySelector('.date-picker')
among a variety of other things. Sample code below. I appreciate any insight you can offer.
Date picker component:
render() {
return html`
<textfield iconalt="Calendar" iconname="calendar" label="Calendar" optionaltext="hide"></textfield>
`;
}
updated() {
var datePickerShadow = this.shadowRoot.querySelector('.date-picker'); // gets el in shadow dom
var datePickerLight = document.querySelector('.date-picker'); // gets el in light dom
var importantDate = [Date.parse('2021-1-27'), Date.parse('2021-1-5'), Date.parse('2021-2-9')];
var datePicker = flatpickr(datePickerLight, {
wrap: true,
disable: ["2021-01-30", "2021-01-21", "2021-01-08", new Date(2025, 4, 9) ],
allowInput: true,
clickOpens: false,
})
}
Advertisement
Answer
If <textfield>
is a custom element then its tagname is illegal: custom element tags must contain at least a -
. This is probably preventing the browser from upgrading it (and thus rendering its content and executing its logic).
Anyway if .date-picker
is inside of <textfield>
‘s template, neither of the querySelector
calls you tried would work: the first selects inside <date-picker>
‘s shadow dom but does not recurse in child components, while the second completely misses shadow doms.
What you can do is:
Use cascaded querySelectors
JavaScript110101class DatePicker extends LitElement {
2
3async firstUpdated() {
4const textField = this.renderRoot.querySelector('text-field');
5await textField.updated; // Wait for first render of text-field
6const datePicker = textField.renderRoot.querySelector('.date-picker');
7}
8
9}
10
Move
.date-picker
in<date-picker>
‘s template if possiblePass
.date-picker
to<text-field>
which renders it in a slotJavaScript110101// This way you can directly select .date-picker
2
3render() {
4return html`
5<text-field>
6<div class="date-picker"></div>
7</text-field>
8`;
9}
10
Instantiate the picker inside
<text-field>
and expose the instance using a property (or part of its functionality through methods and properties).
(I’d avoid the first option if possible)