Özel bir denetimin değerini bir formda göstermek için gizli bir <input> kullanmayın. Formla İlişkili Özel Öğeler (FACE) kullanın: formAssociated ve ElementInternals ile öğe kendi değerini gönderir, doğrulamaya katılır ve form durumunu yerel olarak yansıtır.
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);
Önemli noktalar:
static formAssociated = trueZORUNLUDUR; formla ilgiliElementInternalsyöntemlerinin veformXxxCallbackyaşam döngüsünün kilidini açar.setFormValue(value), gönderim işlemini gerçekleştirir ve gizli giriş gerektirmez. Çoklu değer kontrolleri içinFormDatailetin.setValidity(flags, message, anchor), yerel kısıtlama doğrulamasıyla entegre olur: Form geçersizken gönderilmez,:invalid/:validuygulanır ve bağlantı öğesi raporda odaklanır. Temizlemek içinsetValidity({})numaralı telefonu arayın. Etkileşime duyarlı:user-valid/:user-invalidsözde sınıfları, tarayıcılar genelinde formla ilişkili öğeler için tutarlı bir şekilde bağlanmaz. Bu sınıfların, kullanıcı etkileşimini yerel kontrollerde olduğu gibi izlediğini varsaymak yerine, onlara güvenmeden önce desteği doğrulayın.- Öğenin sıfırlama,
fieldset[disabled]ve geri/ileri otomatik doldurma geri yükleme işlemlerinde yerel bir kontrol gibi davranması içinformResetCallback,formDisabledCallbackveformStateRestoreCallbacköğelerini uygulayın.formDisabledCallback(disabled)içinde, ana makinededisableddeğerini ayarlamak yerine dahili kontrolleri devre dışı bırakın (veya bunları sekme sırasından kaldırıp girişi yoksayın). Geri çağırma içinde ana makine özelliğini ayarlamak, bir üst öğe<fieldset>yeniden etkinleştirildiğinde yeniden etkinleştirmeyi önler ve ana makine zaten:disabledile otomatik olarak eşleşir. - Gönderilen etkinlikler için platform kurallarına uyun ve özel etkinlikler yerine yerleşik
inputvechangeetkinliklerini tercih edin.input, değer doğrudan kullanıcı işleminin (yazma, kaydırma çubuğunu sürükleme) bir sonucu olarak değiştiğinde tetiklenir;change, kullanıcı işlemi tamamladığında (kaydırma çubuğunu bırakma, alanı bulanıklaştırma) değişiklik akışı başına bir kez tetiklenir. Bunları sırasıylaInputEventveEventile oluşturun.
Yedek stratejiler
static formAssociated desteğini kullanmadan önce özellik algılama yapın: 'attachInternals' in HTMLElement.prototype && 'setFormValue' in ElementInternals.prototype. Kullanılamadığı durumlarda, formun gönderilmeye devam etmesi için denetimin değerine senkronize edilmiş, görsel olarak gizlenmiş yerel bir <input> öğesine geri dönün. Bu, gizli giriş kalıbının haklı olduğu tek durumdur.