Form Doğrulama
Gerekli Kontroller
Kontroller, argümanı kullanıcı doldurmazsa görüntülenecek hata mesajının metni olan
setRequired()
yöntemiyle gerekli olarak işaretlenir. Herhangi bir bağımsız değişken verilmezse, varsayılan
hata mesajı kullanılır.
$form->addText('name', 'Name:')
->setRequired('Please fill your name.');
Kurallar
addRule()
metodu ile kontrollere doğrulama kuralları ekleriz. İlk parametre kural, ikincisi hata mesajı, üçüncüsü ise doğrulama kuralı argümanıdır.
$form->addPassword('password', 'Password:')
->addRule($form::MinLength, 'Password must be at least %d characters', 8);
Doğrulama kuralları yalnızca kullanıcı öğeyi doldurduysa kontrol edilir.
Nette, isimleri Nette\Forms\Form
sınıfının sabitleri olan bir dizi önceden tanımlanmış kuralla birlikte
gelir. Bu kuralları tüm öğelere uygulayabiliriz:
sabit | açıklama | argümanlar |
---|---|---|
Required |
setRequired() 'un takma adı |
– |
Filled |
setRequired() 'un takma adı |
– |
Blank |
doldurulmamalıdır | – |
Equal |
değer parametreye eşittir | mixed |
NotEqual |
değer parametreye eşit değil | mixed |
IsIn |
değer dizideki bazı elemanlara eşittir | array |
IsNotIn |
değer dizideki herhangi bir elemana eşit değil | array |
Valid |
girdi doğrulamayı geçer ( koşullar için) | – |
Metin girişleri
addText()
, addPassword()
, addTextArea()
, addEmail()
,
addInteger()
, addFloat()
öğeleri için aşağıdaki kurallardan bazıları da uygulanabilir:
MinLength |
minimum dize uzunluğu | int |
MaxLength |
maksimum dize uzunluğu | int |
Length |
aralıktaki uzunluk veya tam uzunluk | çifti [int, int] veya int |
Email |
geçerli e-posta adresi | – |
URL |
geçerli URL | – |
Pattern |
düzenli kalıpla eşleşir | string |
PatternInsensitive |
Pattern gibi, ancak büyük/küçük harf duyarsız |
string |
Integer |
tamsayı | – |
Numeric |
Integer 'un takma adı |
– |
Float |
tamsayı veya kayan noktalı sayı | – |
Min |
tamsayı değerinin minimum değeri | int|float |
Max |
tamsayı değerinin maksimum değeri | int|float |
Range |
aralıktaki değer | çifti [int|float, int|float] |
Integer
, Numeric
a Float
kuralları değeri otomatik olarak tamsayıya (veya sırasıyla
float) dönüştürür. Ayrıca, URL
kuralı da şeması olmayan bir adresi kabul eder (örneğin
nette.org
) ve şemayı tamamlar (https://nette.org
). Pattern
ve
PatternInsensitive
içindeki ifadeler tüm değer için geçerli olmalıdır, yani ^
and $
karakterlerine sarılmış gibi olmalıdır.
Ürün Sayısı
addMultiUpload()
, addCheckboxList()
, addMultiSelect()
öğeleri için, seçilen
öğelerin veya yüklenen dosyaların sayısını sınırlamak üzere aşağıdaki kuralları da kullanabilirsiniz:
MinLength |
minimum sayı | int |
MaxLength |
maksimum sayı | int |
Length |
aralıktaki sayı veya tam sayı | çiftleri [int, int] veya int |
Dosya Yükleme
addUpload()
, addMultiUpload()
kontrolleri için aşağıdaki kurallar da kullanılabilir:
MaxFileSize |
bayt cinsinden maksimum dosya boyutu | int |
MimeType |
MIME türü, joker karakterleri kabul eder ('video/*' ) |
string|string[] |
Image |
yüklenen dosya JPEG, PNG, GIF, WebP | – |
Pattern |
dosya adı düzenli ifadeyle eşleşiyor | string |
PatternInsensitive |
Pattern gibi, ancak büyük/küçük harf duyarsız |
string |
MimeType
ve Image
PHP uzantısı fileinfo
gerektirir. Bir dosya veya resmin gerekli
türde olup olmadığı imzasından anlaşılır. Tüm dosyanın bütünlüğü kontrol edilmez. Bir resmin bozuk olup
olmadığını örneğin yüklemeye çalışarak
öğrenebilirsiniz.
Hata Mesajları
Pattern
ve PatternInsensitive
dışındaki tüm önceden tanımlanmış kuralların varsayılan bir
hata mesajı vardır, bu nedenle bunlar atlanabilir. Bununla birlikte, tüm özelleştirilmiş mesajları ileterek ve formüle
ederek, formu daha kullanıcı dostu hale getireceksiniz.
Varsayılan mesajları configuration'da,
Nette\Forms\Validator::$messages
dizisindeki metinleri değiştirerek veya çevirmen kullanarak değiştirebilirsiniz.
Hata mesajlarının metninde aşağıdaki joker karakterler kullanılabilir:
%d |
argümanlardan sonraki kuralları kademeli olarak değiştirir |
%n$d |
n'inci kural argümanıyla yer değiştirir |
%label |
alan etiketi ile değiştirir (iki nokta üst üste olmadan) |
%name |
alan adı ile değiştirir (örneğin name ) |
%value |
kullanıcı tarafından girilen değerle değiştirir |
$form->addText('name', 'Name:')
->setRequired('Please fill in %label');
$form->addInteger('id', 'ID:')
->addRule($form::Range, 'at least %d and no more than %d', [5, 10]);
$form->addInteger('id', 'ID:')
->addRule($form::Range, 'no more than %2$d and at least %1$d', [5, 10]);
Koşullar
Doğrulama kurallarının yanı sıra koşullar da belirlenebilir. Bunlar kurallar gibi ayarlanır, ancak
addCondition()
yerine addRule()
kullanırız ve elbette bir hata mesajı olmadan bırakırız (koşul
sadece sorar):
$form->addPassword('password', 'Password:')
// eğer şifre 8 karakterden uzun değilse ...
->addCondition($form::MaxLength, 8)
// ... o zaman bir sayı içermelidir
->addRule($form::Pattern, 'Must contain number', '.*[0-9].*');
Koşul, addConditionOn()
kullanılarak geçerli olandan farklı bir öğeye bağlanabilir. İlk parametre alana
bir referanstır. Aşağıdaki durumda, e-posta yalnızca onay kutusu işaretliyse (yani değeri true
ise) gerekli
olacaktır:
$form->addCheckbox('newsletters', 'send me newsletters');
$form->addEmail('email', 'Email:')
// onay kutusu işaretliyse ...
->addConditionOn($form['newsletters'], $form::Equal, true)
// ... e-posta gerektirir
->setRequired('E-posta adresinizi doldurun');
Koşullar elseCondition()
ve endCondition()
yöntemleri ile karmaşık yapılar halinde
gruplandırılabilir.
$form->addText(/* ... */)
->addCondition(/* ... */) // ilk koşul karşılanırsa
->addConditionOn(/* ... */) // ve ikinci koşulu da başka bir eleman üzerinde
->addRule(/* ... */) // bu kuralı gerektirir
->elseCondition() // ikinci koşul karşılanmazsa
->addRule(/* ... */) // bu kuralları gerektirir
->addRule(/* ... */)
->endCondition() // ilk koşula geri dönüyoruz
->addRule(/* ... */);
Nette, toggle()
yöntemini kullanarak JavaScript tarafında bir koşulun
yerine getirilip getirilmemesine tepki vermek çok kolaydır, bkz.
Başka Bir Öğeye Referans
Bir kural veya koşul için bağımsız değişken olarak başka bir form öğesi de iletebilirsiniz. Kural daha sonra
kullanıcı tarafından tarayıcıda girilen değeri kullanacaktır. Bu, örneğin, password
öğesinin
password_confirm
öğesiyle aynı dizeyi içerdiğini dinamik olarak doğrulamak için kullanılabilir:
$form->addPassword('password', 'Password');
$form->addPassword('password_confirm', 'Confirm Password')
->addRule($form::Equal, 'The passwords do not match', $form['password']);
Özel Kurallar ve Koşullar
Bazen Nette'deki yerleşik doğrulama kurallarının yeterli olmadığı ve kullanıcıdan gelen verileri kendi yöntemimizle doğrulamamız gereken bir durumla karşılaşırız. Nette'de bu çok kolaydır!
addRule()
veya addCondition()
yöntemlerine ilk parametre olarak herhangi bir geri çağırma
iletebilirsiniz. Geri arama, öğenin kendisini ilk parametre olarak kabul eder ve doğrulamanın başarılı olup olmadığını
gösteren bir boolean değeri döndürür. addRule()
kullanarak bir kural eklerken, ek argümanlar geçirilebilir ve
bunlar daha sonra ikinci parametre olarak geçirilir.
Özel doğrulayıcı kümesi böylece statik yöntemlere sahip bir sınıf olarak oluşturulabilir:
class MyValidators
{
// değerin argüman tarafından bölünebilir olup olmadığını test eder
public static function validateDivisibility(BaseControl $input, $arg): bool
{
return $input->getValue() % $arg === 0;
}
public static function validateEmailDomain(BaseControl $input, $domain)
{
// ek doğrulayıcılar
}
}
Bu durumda kullanım çok basittir:
$form->addInteger('num')
->addRule(
[MyValidators::class, 'validateDivisibility'],
'The value must be a multiple of %d',
8,
);
Özel doğrulama kuralları JavaScript'e de eklenebilir. Tek gereklilik, kuralın statik bir yöntem olmasıdır. JavaScript
doğrulayıcısı için adı, ters eğik çizgiler olmadan sınıf adı \
, the underscore _
, ve yöntem
adı birleştirilerek oluşturulur. Örneğin, App\MyValidators::validateDivisibility
öğesini
AppMyValidators_validateDivisibility
olarak yazın ve Nette.validators
nesnesine ekleyin:
Nette.validators['AppMyValidators_validateDivisibility'] = (elem, args, val) => {
return val % args === 0;
};
Olay onValidate
Form gönderildikten sonra, addRule()
tarafından eklenen kurallar tek tek kontrol edilerek ve ardından
onValidate
olayı çağrılarak doğrulama
gerçekleştirilir. İşleyicisi, tipik olarak birden fazla form öğesindeki değerlerin doğru kombinasyonunu doğrulamak üzere
ek doğrulama için kullanılabilir.
Bir hata tespit edilirse, bu hata addError()
yöntemi kullanılarak forma iletilir. Bu, belirli bir öğe
üzerinde veya doğrudan form üzerinde çağrılabilir.
protected function createComponentSignInForm(): Form
{
$form = new Form;
// ...
$form->onValidate[] = [$this, 'validateSignInForm'];
return $form;
}
public function validateSignInForm(Form $form, \stdClass $data): void
{
if ($data->foo > 1 && $data->bar > 5) {
$form->addError('Bu kombinasyon mümkün değil.');
}
}
İşleme Hataları
Çoğu durumda, geçerli bir formu işlerken bir hata keşfederiz, örneğin veritabanına yeni bir girdi yazdığımızda ve
yinelenen bir anahtarla karşılaştığımızda. Bu durumda, addError()
yöntemini kullanarak hatayı forma geri
iletiriz. Bu, belirli bir öğe üzerinde ya da doğrudan form üzerinde çağrılabilir:
try {
$data = $form->getValues();
$this->user->login($data->username, $data->password);
$this->redirect('Home:');
} catch (Nette\Security\AuthenticationException $e) {
if ($e->getCode() === Nette\Security\Authenticator::InvalidCredential) {
$form->addError('Invalid password.');
}
}
Mümkünse, hatayı doğrudan form öğesine eklemenizi öneririz, çünkü varsayılan oluşturucu kullanılırken yanında görünecektir.
$form['date']->addError('Sorry, this date is already taken.');
Bir forma veya öğeye birden fazla hata mesajı iletmek için addError()
adresini tekrar tekrar
çağırabilirsiniz. Bunları getErrors()
ile alırsınız.
$form->getErrors()
adresinin, yalnızca doğrudan forma değil, doğrudan tek tek öğelere iletilenler de
dahil olmak üzere tüm hata mesajlarının bir özetini döndürdüğünü unutmayın. Yalnızca forma iletilen hata mesajları
$form->getOwnErrors()
aracılığıyla alınır.
Girdi Değerlerini Değiştirme
addFilter()
yöntemini kullanarak, kullanıcı tarafından girilen değeri değiştirebiliriz. Bu örnekte, posta
kodundaki boşlukları tolere edeceğiz ve kaldıracağız:
$form->addText('zip', 'Posta kodu:')
->addFilter(function ($value) {
return str_replace(' ', '', $value); // posta kodundan boşlukları kaldır
})
->addRule($form::Pattern, 'The postal code is not five digits', '\d{5}');
Filtre, doğrulama kuralları ve koşulları arasında yer alır ve bu nedenle yöntemlerin sırasına bağlıdır; yani filtre
ve kural, addFilter()
ve addRule()
yöntemlerinin sırası ile aynı sırada çağrılır.
JavaScript Doğrulama
Doğrulama kuralları ve koşullarının dili güçlüdür. Tüm yapılar JavaScript'te hem sunucu tarafında hem de istemci
tarafında çalışsa da. Kurallar HTML özelliklerinde data-nette-rules
JSON olarak aktarılır. Doğrulamanın
kendisi, tüm formun submit
olaylarını bağlayan, tüm girdileri yineleyen ve ilgili doğrulamaları çalıştıran
başka bir komut dosyası tarafından gerçekleştirilir.
Bu komut dosyası, birkaç olası kaynaktan temin edilebilen netteForms.js
adresindedir:
Komut dosyasını CDN'den doğrudan HTML sayfasına gömebilirsiniz:
<script src="https://unpkg.com/nette-forms@3"></script>
Ya da yerel olarak projenin ortak klasörüne kopyalayın (örneğin
vendor/nette/forms/src/assets/netteForms.min.js
adresinden):
<script src="/path/to/netteForms.min.js"></script>
Veya npm aracılığıyla yükleyin:
npm install nette-forms
Ve sonra yükleyin ve çalıştırın:
import netteForms from 'nette-forms';
netteForms.initOnLoad();
Alternatif olarak, doğrudan vendor
klasöründen de yükleyebilirsiniz:
import netteForms from '../path/to/vendor/nette/forms/src/assets/netteForms.js';
netteForms.initOnLoad();
Dinamik JavaScript
Adres alanlarını yalnızca kullanıcı ürünleri postayla göndermeyi seçerse mi göstermek istiyorsunuz? Hiç sorun
değil. Anahtar bir çift yöntemdir addCondition()
& toggle()
:
$form->addCheckbox('send_it')
->addCondition($form::Equal, true)
->toggle('#address-container');
Bu kod, koşul karşılandığında, yani onay kutusu işaretlendiğinde, #address-container
HTML öğesinin
görünür olacağını söyler. Ve tam tersi. Böylece, alıcının adresini içeren form öğelerini bu kimliğe sahip bir
kapsayıcıya yerleştiririz ve onay kutusu tıklandığında gizlenir veya gösterilir. Bu işlem netteForms.js
komut dosyası tarafından gerçekleştirilir.
Herhangi bir seçici toggle()
yöntemine argüman olarak aktarılabilir. Tarihsel nedenlerden dolayı, başka
hiçbir özel karakter içermeyen alfanümerik bir dize, önünde #
character. The second optional parameter allows
us to reverse the behavior, i.e. if we used toggle('#address-container', false)
olduğu gibi bir öğe kimliği
olarak kabul edilir, öğe yalnızca onay kutusu işaretlenmemişse görüntülenir.
Varsayılan JavaScript uygulaması, öğeler için hidden
özelliğini değiştirir. Ancak, örneğin bir
animasyon ekleyerek davranışı kolayca değiştirebiliriz. JavaScript'teki Nette.toggle
yöntemini özel bir
çözümle geçersiz kılmanız yeterlidir:
Nette.toggle = (selector, visible, srcElement, event) => {
document.querySelectorAll(selector).forEach((el) => {
// hide or show 'el' according to the value of 'visible'
});
};
Doğrulamayı Devre Dışı Bırakma
Bazı durumlarda doğrulamayı devre dışı bırakmanız gerekir. Bir gönderme düğmesinin gönderme işleminden sonra
doğrulama yapmaması gerekiyorsa (örneğin İptal veya Önizleme düğmesi),
$submit->setValidationScope([])
adresini çağırarak doğrulamayı devre dışı bırakabilirsiniz. Ayrıca,
doğrulanacak öğeleri belirterek formu kısmen doğrulayabilirsiniz.
$form->addText('name')
->setRequired();
$details = $form->addContainer('details');
$details->addInteger('age')
->setRequired('age');
$details->addInteger('age2')
->setRequired('age2');
$form->addSubmit('send1'); // Tüm formu doğrular
$form->addSubmit('send2')
->setValidationScope([]); // Hiçbir şeyi doğrulamaz
$form->addSubmit('send3')
->setValidationScope([$form['name']]); // Yalnızca 'name' alanını doğrular
$form->addSubmit('send4')
->setValidationScope([$form['details']['age']]); // Yalnızca 'age' alanını doğrular
$form->addSubmit('send5')
->setValidationScope([$form['details']]); // Validates 'details' container
Form üzerindeki onValidate olayı her zaman çağrılır ve
setValidationScope
adresinden etkilenmez. onValidate
kapsayıcı üzerindeki olay yalnızca bu
kapsayıcı kısmi doğrulama için belirtildiğinde çağrılır.