# 11. Hafta — Form ve Doğrulama

## Bu hafta ne yapacağız?

Ad, okul e-postası ve parola alanlarından oluşan öğrenci hesabı formu geliştireceğiz. Boş, biçimi bozuk veya yetersiz girdilerde alanın yanında hata göstereceğiz; yalnız bütün alanlar geçerliyse başarı özeti oluşturacağız. Ardından gerçek bir Flutter atölyesi için ayrıntılı başvuru formu yapacağız.

## Kazanımlar

- `Form` ve `GlobalKey<FormState>` ile alanları birlikte yönetme
- `TextFormField.validator` ile alan bazlı doğrulama
- Düzenli ifadeyle e-posta ve okul numarası kontrol etme
- Parolayı gizleme/gösterme ve controller yaşam döngüsünü yönetme
- Geçerli formdan güvenli bir başarı özeti üretme

## Uygulama 11 — Öğrenci Kayıt Formu

### 1. Form anahtarını oluşturma

```dart
final formKey = GlobalKey<FormState>();

Form(
  key: formKey,
  child: ListView(children: [...]),
)
```

Anahtar, farklı alanlardaki validator sonuçlarına tek noktadan ulaşır.

### 2. Boş alan kontrolü

```dart
String? bosKontrol(String? deger, String alan) {
  return deger == null || deger.trim().isEmpty
      ? '$alan boş bırakılamaz.'
      : null;
}
```

Validator hata varsa metin, geçerliyse `null` döndürür.

### 3. E-posta biçimini doğrulama

```dart
validator: (deger) {
  if (deger == null || deger.trim().isEmpty) {
    return 'E-posta boş bırakılamaz.';
  }
  if (!RegExp(r'^[^@\s]+@[^@\s]+\.[^@\s]+$').hasMatch(deger)) {
    return 'Geçerli bir e-posta giriniz.';
  }
  return null;
}
```

### 4. Parola görünürlüğü ve kuralları

Parola en az sekiz karakter ve en az bir rakam içermelidir. Göz düğmesi `obscureText` durumunu değiştirir:

```dart
IconButton(
  onPressed: () => setState(() => gizli = !gizli),
  icon: Icon(gizli ? Icons.visibility : Icons.visibility_off),
)
```

### 5. Formu göndermek

```dart
void kaydet() {
  final gecerli = formKey.currentState!.validate();
  setState(() => kayitBasarili = gecerli);
}
```

Testte geçerli alanlarla form gönderildi; hesap oluşturma başlığı ve doğru e-posta içeren özet doğrulandı.

![Başarıyla tamamlanmış Öğrenci Kayıt Formu](../../screenshots/week-11-adapted.png)

## Özgün proje — Etkinlik Başvurusu

Atölye formu farklı doğrulama çeşitlerini aynı senaryoda birleştirir:

- Ad soyad en az 3 karakterdir.
- Okul numarası tam 4 rakamdır.
- Katılma nedeni en az 20 karakterdir.
- Sınıf açılır listeden seçilir.
- Kurallar kabul edilmeden gönderme düğmesi etkinleşmez.

### Dört haneli numara kontrolü

```dart
validator: (deger) {
  if (deger == null || !RegExp(r'^\d{4}$').hasMatch(deger)) {
    return '4 haneli numara giriniz.';
  }
  return null;
}
```

### Koşula bağlı düğme

```dart
FilledButton.icon(
  onPressed: izin ? gonder : null,
  icon: const Icon(Icons.send),
  label: const Text('Başvuruyu gönder'),
)
```

`onPressed: null`, kurallar kabul edilmediğinde düğmeyi hem işlevsel hem görsel olarak devre dışı bırakır. Başarılı gönderimde ad, sınıf ve numara özet kartında gösterilir. Testte Mert Kaya’nın 11/A sınıfından 1124 numarasıyla başvurusu doğrulandı.

![Başarıyla gönderilmiş Flutter Atölyesi Başvurusu](../../screenshots/week-11-original.png)

## Sıra sende

1. Kolay: Kayıt formuna telefon alanı ekle.
2. Orta: Etkinlik formuna iki farklı atölye seçeneği ekle.
3. İleri: Parolanın büyük harf, küçük harf, rakam ve özel karakter kurallarını ayrı göstergelerle canlı kontrol et.

Çözümünü gönderdikten ve geri bildirim aldıktan sonra Etkinlik Başvurusu’nun gerçek Dart kodu ile çalışan proje paketi açılacaktır. İpucu doğru validator koşulunu kurduracak; çözüm düğmesi eksiksiz `lib/main.dart` içeriğini gösterecektir.

## Kontrol listesi

- Bütün form alanları tek `Form` ve `GlobalKey` ile yönetiliyor.
- Her validator hata metni veya `null` döndürüyor.
- Başarı özeti yalnız geçerli formdan sonra görünüyor.
- Controller’lar `dispose` içinde kapatılıyor.
- İki proje Flutter widget testinden geçti ve gerçek ekran çıktıları görsel olarak doğrulandı.
