Gebruik geen verborgen <input> om de waarde van een aangepast bedieningselement in een formulier te tonen. Gebruik aan formulieren gekoppelde aangepaste elementen (FACE): met formAssociated en ElementInternals dient het element de eigen waarde in, neemt het deel aan validatie en weerspiegelt het de formulierstatus op een native manier.
class RatingInput extends HTMLElement {
// MANDATORY: opt in. Without this, attachInternals() form APIs are unavailable.
static formAssociated = true;
#internals;
#value = '';
constructor() {
super();
this.#internals = this.attachInternals();
this.attachShadow({ mode: 'open', delegatesFocus: true });
}
connectedCallback() {
// Validate initial state once attributes (such as `required`) are present.
this.#validate();
}
get value() { return this.#value; }
set value(v) {
this.#value = v;
// Push the value into the owning <form> for submission.
this.#internals.setFormValue(v);
this.#validate();
}
#validate() {
if (this.hasAttribute('required') && !this.#value) {
// Mark invalid and supply the native validation message + anchor.
this.#internals.setValidity(
{ valueMissing: true },
'Please choose a rating.',
this.shadowRoot.querySelector('[tabindex]'),
);
} else {
this.#internals.setValidity({}); // clear
}
}
// Optional FACE lifecycle hooks:
formResetCallback() { this.value = ''; }
formDisabledCallback(disabled) {
// Disable internal controls so they leave the tab order and ignore clicks.
// Do NOT toggle `disabled` on `this`, or a `<fieldset disabled>` toggle will
// leave the host permanently stuck with its own `disabled` attribute.
for (const el of this.shadowRoot.querySelectorAll('button')) {
el.disabled = disabled;
}
}
formStateRestoreCallback(state) { this.value = state; }
}
customElements.define('rating-input', RatingInput);
Belangrijke punten:
static formAssociated = trueis VERPLICHT. Hiermee worden de formuliergerelateerdeElementInternals-methoden en deformXxxCallback-levenscyclus ontgrendeld.setFormValue(value)is wat wordt ingediend, zonder dat er verborgen invoer is vereist. Geef eenFormDatadoor voor bedieningselementen met meerdere waarden.setValidity(flags, message, anchor)integreert met native beperkingsvalidatie: het formulier wordt niet ingediend als het ongeldig is,:invalid/:validzijn van toepassing en het ankerelement krijgt de focus in het rapport. BelsetValidity({})om te wissen. De interactiebewuste pseudoklassen:user-valid/:user-invalidzijn niet consistent verbonden met formuliergerelateerde elementen in verschillende browsers. Controleer de ondersteuning voordat je erop vertrouwt in plaats van aan te nemen dat ze de gebruikersinteractie bijhouden zoals ze dat doen voor systeemeigen bedieningselementen.- Implementeer
formResetCallback,formDisabledCallbackenformStateRestoreCallbackzodat het element zich gedraagt als een systeemeigen bedieningselement bij resetten,fieldset[disabled]en herstel van automatisch invullen bij terug/vooruit. Zet informDisabledCallback(disabled)interne bedieningselementen uit (of verwijder ze uit de tabvolgorde en negeer invoer) in plaats vandisabledin te stellen op de host. Als je het hostkenmerk instelt in de callback, wordt het niet opnieuw aangezet als een bovenliggende<fieldset>opnieuw wordt aangezet en de host al automatisch overeenkomt met:disabled. - Volg de platformconventies voor verzonden gebeurtenissen en geef de voorkeur aan de ingebouwde gebeurtenissen
inputenchangeboven aangepaste gebeurtenissen.inputwordt geactiveerd als de waarde verandert als direct gevolg van een gebruikersactie (typen, een schuifregelaar slepen).changewordt één keer per stream van wijzigingen geactiveerd wanneer de gebruiker de wijziging bevestigt (de schuifregelaar loslaten, het veld vervagen). Maak ze met respectievelijkInputEventenEvent.
Reservestrategieën
Voer een functiedetectie uit met static formAssociated-ondersteuning voordat je erop vertrouwt: 'attachInternals' in HTMLElement.prototype && 'setFormValue' in ElementInternals.prototype. Als deze niet beschikbaar is, gebruik je een visueel verborgen systeemeigen <input> die is gesynchroniseerd met de waarde van het bedieningselement, zodat het formulier nog steeds wordt ingediend. Dit is het enige geval waarin het patroon voor verborgen invoer gerechtvaardigd is.