Reputation: 65
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,
})
}
Upvotes: 3
Views: 3110
Reputation: 3142
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
class DatePicker extends LitElement {
async firstUpdated() {
const textField = this.renderRoot.querySelector('text-field');
await textField.updated; // Wait for first render of text-field
const datePicker = textField.renderRoot.querySelector('.date-picker');
}
}
Move .date-picker
in <date-picker>
's template if possible
Pass .date-picker
to <text-field>
which renders it in a slot
// This way you can directly select .date-picker
render() {
return html`
<text-field>
<div class="date-picker"></div>
</text-field>
`;
}
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)
Upvotes: 2