- Konu sahibi
- #1
Form gönderildiğinde düğmeyi devre dışı bırakmak için işlemi düğmenin
Aşağıdaki örnekte HTML formu ve gönderme düğmesi birlikte bulunur. Form gönderildiğinde önce
Kullanıcı formu geçerli bilgilerle gönderdiğinde düğme pasif hâle gelir ve metni
Form verisini
Bu kodda
İstek başarılı olduğunda kullanıcıya başarı mesajı gösterilir ve form temizlenir. İstek başarısız olduğunda hata mesajı gösterilir.
Form alanlarını JSON olarak göndermek istiyorsanız
Bu kullanımda sunucunun JSON gövdesini kabul edecek şekilde yapılandırılmış olması gerekir. Yalnızca düğmeyi devre dışı bırakmak, sunucunun isteği kabul edeceği veya kaydı oluşturacağı anlamına gelmez.
Örneğin e-posta alanı boş bırakılırsa tarayıcı doğrulama mesajını gösterir ve form gönderilmez. Bu durumda düğmenin devre dışı kalmaması gerekir. Alanlar geçerli olduğunda
Birden fazla gönderim olasılığını ayrıca güvenceye almak istiyorsanız işlem başlamadan önce düğmenin durumunu kontrol edebilirsiniz:
Bu kontrol, aynı olayın uygulama içindeki başka bir kod tarafından yeniden tetiklenmesi gibi durumlarda ek koruma sağlar. Yine de asıl güvenlik önlemi sunucuda alınmalıdır; istemci tarafındaki
Kullanacağınız davranış, form gönderiminin sonucuna bağlıdır:
Ağ hatası durumunda düğmeyi açmak, ilk isteğin kesinlikle sunucuya ulaşmadığını kanıtlamaz. İstek sunucuya ulaşmış ancak yanıt kullanıcıya dönememiş olabilir. Ödeme, sipariş veya benzeri tekrarlı işlemlerde yalnızca düğmeyi kilitlemek yeterli değildir; sunucu tarafında benzersiz işlem anahtarı veya benzeri bir yineleme önleme mekanizması kullanılmalıdır.
Düğmeye yalnızca
Düğmeyi devre dışı bıraktıktan sonra isteği başlatmayı unutursanız kullanıcı yalnızca pasif bir düğme görür ve işlem gerçekleşmez.
Ayrıca
Özetle, normal form gönderiminde
click olayına değil, formun submit olayına bağlayın. Böylece kullanıcı düğmeye tıklayarak veya Enter tuşuyla gönderim yaptığında aynı kod çalışır. event.preventDefault() ile gönderimi JavaScript içinde yönetiyorsanız, gönderim başlamadan önce düğmenin disabled özelliğini true yapın; işlem başarısız olursa veya form yeniden kullanılacaksa false değerine geri döndürün.En basit kullanım
Aşağıdaki örnekte HTML formu ve gönderme düğmesi birlikte bulunur. Form gönderildiğinde önce
submit olayı yakalanır, ardından düğme devre dışı bırakılır. preventDefault() kullanıldığı için tarayıcının normal sayfa yenilemeli form gönderimi durdurulur.
HTML:
<form id="contactForm">
<label for="email">E-posta</label>
<input id="email" name="email" type="email" required>
<button id="submitButton" type="submit">Gönder</button>
</form>
<script>
const form = document.querySelector('#contactForm');
const submitButton = document.querySelector('#submitButton');
form.addEventListener('submit', function (event) {
event.preventDefault();
submitButton.disabled = true;
submitButton.textContent = 'Gönderiliyor...';
// Burada form gönderme işlemini yapabilirsiniz.
});
</script>
Kullanıcı formu geçerli bilgilerle gönderdiğinde düğme pasif hâle gelir ve metni
Gönderiliyor... olur. disabled özelliği, düğmenin yeniden tıklanmasını ve klavye üzerinden yeniden tetiklenmesini engeller. Ancak bu örnekte işlem tamamlandıktan sonra düğme tekrar etkinleştirilmez; sayfayı başka bir adrese yönlendirecek veya başarılı gönderimden sonra formu kapatacaksanız bu davranış uygun olabilir.Fetch ile gönderimde düğmeyi yeniden etkinleştirme
Form verisini
fetch() ile sunucuya gönderiyorsanız, düğmeyi işlem başlamadan önce kapatıp işlemin sonucuna göre yönetebilirsiniz. finally bloğu, istek başarılı olsun veya hata versin, düğmenin tekrar etkinleştirilmesi gereken ortak noktadır.
HTML:
<form id="contactForm">
<label for="email">E-posta</label>
<input id="email" name="email" type="email" required>
<button id="submitButton" type="submit">Gönder</button>
<p id="message" role="status"></p>
</form>
<script>
const form = document.querySelector('#contactForm');
const submitButton = document.querySelector('#submitButton');
const message = document.querySelector('#message');
form.addEventListener('submit', async function (event) {
event.preventDefault();
submitButton.disabled = true;
submitButton.textContent = 'Gönderiliyor...';
message.textContent = '';
const formData = new FormData(form);
try {
const response = await fetch('/api/contact', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error('Sunucu isteği başarısız oldu.');
}
message.textContent = 'Form başarıyla gönderildi.';
form.reset();
} catch (error) {
message.textContent = 'Gönderim sırasında bir hata oluştu. Lütfen tekrar deneyin.';
} finally {
submitButton.disabled = false;
submitButton.textContent = 'Gönder';
}
});
</script>
Bu kodda
/api/contact yalnızca örnek bir uç noktadır; kendi sunucu adresinizle değiştirilmelidir. response.ok değerinin olumlu olması, isteğin HTTP düzeyinde başarılı olduğunu gösterir; sunucunun form verisini iş kurallarınıza göre doğru kabul ettiğini tek başına kanıtlamaz. Sunucunun ayrıca JSON veya başka bir yanıt gövdesi döndürmesi gerekiyorsa bu yanıtı okuyup kontrol etmelisiniz.İstek başarılı olduğunda kullanıcıya başarı mesajı gösterilir ve form temizlenir. İstek başarısız olduğunda hata mesajı gösterilir.
finally bloğu sayesinde düğme tekrar etkinleşir; kullanıcı hatayı düzelterek formu yeniden gönderebilir.Sunucuya JSON gönderiyorsanız
Form alanlarını JSON olarak göndermek istiyorsanız
FormData yerine alanları JavaScript nesnesine dönüştürün ve Content-Type başlığını belirtin.
JavaScript:
const data = {
email: form.elements.email.value
};
const response = await fetch('/api/contact', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
Bu kullanımda sunucunun JSON gövdesini kabul edecek şekilde yapılandırılmış olması gerekir. Yalnızca düğmeyi devre dışı bırakmak, sunucunun isteği kabul edeceği veya kaydı oluşturacağı anlamına gelmez.
Doğrulama ve tekrar gönderim davranışı
required, type="email" ve benzeri HTML doğrulamaları kullanıyorsanız tarayıcı geçersiz alanlarda normal submit olayını çalıştırmadan önce kullanıcıya alan hatasını gösterebilir. Bu nedenle formun submit olayında düğmeyi devre dışı bırakmak, geçersiz form nedeniyle düğmenin gereksiz yere kilitlenmesini önleyen doğru yaklaşımdır.Örneğin e-posta alanı boş bırakılırsa tarayıcı doğrulama mesajını gösterir ve form gönderilmez. Bu durumda düğmenin devre dışı kalmaması gerekir. Alanlar geçerli olduğunda
submit olayına ulaşılır ve düğme kapatılır.Birden fazla gönderim olasılığını ayrıca güvenceye almak istiyorsanız işlem başlamadan önce düğmenin durumunu kontrol edebilirsiniz:
JavaScript:
form.addEventListener('submit', async function (event) {
event.preventDefault();
if (submitButton.disabled) {
return;
}
submitButton.disabled = true;
try {
// Asenkron gönderim işlemi
} finally {
submitButton.disabled = false;
}
});
Bu kontrol, aynı olayın uygulama içindeki başka bir kod tarafından yeniden tetiklenmesi gibi durumlarda ek koruma sağlar. Yine de asıl güvenlik önlemi sunucuda alınmalıdır; istemci tarafındaki
disabled özelliği kullanıcı arayüzünü kontrol eder, kötü niyetli veya doğrudan oluşturulmuş HTTP isteklerini engellemez.Düğmenin ne zaman yeniden etkinleştirileceği
Kullanacağınız davranış, form gönderiminin sonucuna bağlıdır:
| Durum | Düğme davranışı | Gerekçe |
|---|---|---|
| Sayfa başarılı gönderimden sonra başka adrese yönleniyor | Tekrar etkinleştirmek gerekmeyebilir | Kullanıcı aynı sayfadaki formu yeniden göndermeyecektir |
| Fetch isteği başarılı oluyor ve form aynı sayfada kalıyor | Başarılı işlemden sonra karar verilmelidir | Yeni kayıt oluşturulmasını istemiyorsanız düğme kapalı kalabilir |
| Sunucu hata döndürüyor | Tekrar etkinleştirilmelidir | Kullanıcı hatayı düzeltip yeniden deneyebilmelidir |
| İstek zaman aşımına uğruyor veya ağ kesiliyor | Genellikle tekrar etkinleştirilmelidir | İlk isteğin sunucuda işlenip işlenmediği ayrıca kontrol edilmelidir |
Yaygın hatalar
Düğmeye yalnızca
click olayı eklemek, formun Enter tuşuyla gönderilmesini kapsamayabilir. Bu nedenle form gönderimini kontrol eden ana kod form.addEventListener('submit', ...) içinde olmalıdır.Düğmeyi devre dışı bıraktıktan sonra isteği başlatmayı unutursanız kullanıcı yalnızca pasif bir düğme görür ve işlem gerçekleşmez.
disabled = true satırı, gerçek gönderim kodundan hemen önce yer almalıdır.Ayrıca
finally kullanılmadan yalnızca başarılı sonuçta düğmeyi açmak, ağ veya sunucu hatasında düğmenin kalıcı olarak pasif kalmasına neden olabilir. Tekrar denemeye izin verilen formlarda düğmeyi finally içinde etkinleştirmek daha güvenlidir.Özetle, normal form gönderiminde
submit olayını yakalayıp submitButton.disabled = true kullanın. JavaScript ile asenkron gönderim yapıyorsanız isteği try...catch...finally yapısına alın; hata durumunda kullanıcıya sonucu bildirin ve yeniden denemesi gerekiyorsa düğmeyi finally içinde tekrar etkinleştirin.