Validasi
Pengantar
Nylo Website v7 menyediakan sistem validasi yang dibangun di sekitar class FormValidator. Anda dapat memvalidasi data di dalam halaman menggunakan metode check(), atau menggunakan FormValidator secara langsung untuk validasi mandiri dan tingkat field.
// Validate data in a NyPage/NyState using check()
check((validate) {
validate.that('user@example.com').email();
validate.that('Anthony')
.capitalized()
.maxLength(50);
}, onSuccess: () {
print("All validations passed!");
});
// FormValidator with form fields
Field.text("Email", validator: FormValidator.email())
Memvalidasi Data dengan check()
Di dalam NyPage mana pun, gunakan metode check() untuk memvalidasi data. Metode ini menerima callback yang menerima daftar validator. Gunakan .that() untuk menambahkan data dan merangkai aturan:
class _RegisterPageState extends NyPage<RegisterPage> {
void handleForm() {
check((validate) {
validate.that(_emailController.text, label: "Email").email();
validate.that(_passwordController.text, label: "Password")
.notEmpty()
.password(strength: 2);
}, onSuccess: () {
// All validations passed
_submitForm();
}, onValidationError: (FormValidationResponseBag bag) {
// Validation failed
print(bag.firstErrorMessage);
});
}
}
Cara Kerja check()
check()membuatList<FormValidator>kosong- Callback Anda menggunakan
.that(data)untuk menambahkanFormValidatorbaru dengan data ke daftar - Setiap
.that()mengembalikanFormValidatoryang dapat Anda rangkai aturannya - Setelah callback, setiap validator dalam daftar diperiksa
- Hasil dikumpulkan ke dalam
FormValidationResponseBag
Memvalidasi Beberapa Field
check((validate) {
validate.that(_nameController.text, label: "Name").notEmpty().capitalized();
validate.that(_emailController.text, label: "Email").email();
validate.that(_phoneController.text, label: "Phone").phoneNumberUs();
validate.that(_ageController.text, label: "Age").numeric().minValue(18);
}, onSuccess: () {
_submitForm();
});
Parameter label opsional mengatur nama yang mudah dibaca yang digunakan dalam pesan error (misalnya, "The Email must be a valid email address.").
Hasil Validasi
Metode check() mengembalikan FormValidationResponseBag (sebuah List<FormValidationResult>), yang juga dapat Anda periksa secara langsung:
FormValidationResponseBag bag = check((validate) {
validate.that(_emailController.text, label: "Email").email();
validate.that(_passwordController.text, label: "Password")
.password(strength: 1);
});
if (bag.isValid) {
print("All valid!");
} else {
// Get the first error message
String? error = bag.firstErrorMessage;
print(error);
// Get all failed results
List<FormValidationResult> errors = bag.validationErrors;
// Get all successful results
List<FormValidationResult> successes = bag.validationSuccess;
}
FormValidationResult
Setiap FormValidationResult merepresentasikan hasil validasi satu nilai:
FormValidator validator = FormValidator(data: "test@email.com")
.email()
.maxLength(50);
FormValidationResult result = validator.check();
if (result.isValid) {
print("Valid!");
} else {
// First error message
String? message = result.getFirstErrorMessage();
// All error messages
List<String> messages = result.errorMessages();
// Error responses
List<FormValidationError> errors = result.errorResponses;
}
Menggunakan FormValidator
FormValidator dapat digunakan secara mandiri atau dengan form field.
Penggunaan Mandiri
// Using a named constructor
FormValidator validator = FormValidator.email();
FormValidationResult result = validator.check("user@example.com");
if (result.isValid) {
print("Email is valid");
} else {
String? errorMessage = result.getFirstErrorMessage();
print("Error: $errorMessage");
}
Dengan Data di Constructor
FormValidator validator = FormValidator(data: "user@example.com", attribute: "Email")
.email()
.maxLength(50);
FormValidationResult result = validator.check();
print(result.isValid); // true
Konstruktor Bernama FormValidator
Nylo Website v7 menyediakan konstruktor bernama untuk validasi umum:
// Email validation
FormValidator.email(message: "Please enter a valid email")
// Password validation (strength 1 or 2)
FormValidator.password(strength: 1)
FormValidator.password(strength: 2, message: "Password too weak")
// Phone numbers
FormValidator.phoneNumberUk()
FormValidator.phoneNumberUs()
// URL validation
FormValidator.url()
// Length constraints
FormValidator.minLength(5, message: "Too short")
FormValidator.maxLength(100, message: "Too long")
// Value constraints
FormValidator.minValue(18, message: "Must be 18+")
FormValidator.maxValue(100)
// Size constraints (for lists/strings)
FormValidator.minSize(2, message: "Select at least 2")
FormValidator.maxSize(5)
// Not empty
FormValidator.notEmpty(message: "This field is required")
// Contains values
FormValidator.contains(['option1', 'option2'])
// Starts/ends with
FormValidator.beginsWith("https://")
FormValidator.endsWith(".com")
// Boolean checks
FormValidator.booleanTrue(message: "Must accept terms")
FormValidator.booleanFalse()
// Numeric
FormValidator.numeric()
// Date validations
FormValidator.date()
FormValidator.dateInPast()
FormValidator.dateInFuture()
FormValidator.dateAgeIsOlder(18, message: "Must be 18+")
FormValidator.dateAgeIsYounger(65)
// Text case
FormValidator.uppercase()
FormValidator.lowercase()
FormValidator.capitalized()
// Location formats
FormValidator.zipcodeUs()
FormValidator.postcodeUk()
// Regex pattern
FormValidator.regex(r'^[A-Z]{3}\d{4}$', message: "Invalid format")
// Custom validation
FormValidator.custom(
message: "Invalid value",
validate: (data) => data != null,
)
Merangkai Aturan Validasi
Rangkai beberapa aturan secara lancar menggunakan metode instance. Setiap metode mengembalikan FormValidator, memungkinkan Anda membangun aturan:
FormValidator validator = FormValidator()
.notEmpty()
.email()
.maxLength(50);
FormValidationResult result = validator.check("user@example.com");
if (!result.isValid) {
List<String> errors = result.errorMessages();
print(errors);
}
Semua konstruktor bernama memiliki metode instance yang dapat dirangkai:
FormValidator()
.notEmpty(message: "Required")
.email(message: "Invalid email")
.minLength(5, message: "Too short")
.maxLength(100, message: "Too long")
.beginsWith("user", message: "Must start with 'user'")
.lowercase(message: "Must be lowercase")
Validasi Kustom
Aturan Kustom (Inline)
Gunakan .custom() untuk menambahkan logika validasi inline:
FormValidator.custom(
message: "Username already taken",
validate: (data) {
// Return true if valid, false if invalid
return !_takenUsernames.contains(data);
},
)
Atau rangkai dengan aturan lain:
FormValidator()
.notEmpty()
.custom(
message: "Must start with a letter",
validate: (data) => RegExp(r'^[a-zA-Z]').hasMatch(data.toString()),
)
Validasi Kesetaraan
Periksa apakah nilai cocok dengan yang lain:
FormValidator()
.notEmpty()
.equals(
_passwordController.text,
message: "Passwords must match",
)
Menggunakan FormValidator dengan Field
FormValidator terintegrasi dengan widget Field di form. Berikan validator ke parameter validator:
class RegisterForm extends NyFormData {
RegisterForm({String? name}) : super(name ?? "register");
@override
fields() => [
Field.text(
"Name",
autofocus: true,
validator: FormValidator.notEmpty(),
),
Field.email("Email", validator: FormValidator.email()),
Field.password(
"Password",
validator: FormValidator.password(strength: 1),
),
];
}
Anda juga dapat menggunakan validator berantai dengan field:
Field.text(
"Username",
validator: FormValidator()
.notEmpty(message: "Username is required")
.minLength(3, message: "At least 3 characters")
.maxLength(20, message: "At most 20 characters"),
)
Field.slider(
"Rating",
validator: FormValidator.minValue(4, message: "Rating must be at least 4"),
)
Aturan Validasi yang Tersedia
Semua aturan yang tersedia untuk FormValidator, baik sebagai konstruktor bernama maupun metode yang dapat dirangkai:
| Aturan | Konstruktor Bernama | Metode Berantai | Deskripsi |
|---|---|---|---|
FormValidator.email() |
.email() |
Memvalidasi format email | |
| Password | FormValidator.password(strength: 1) |
.password(strength: 1) |
Strength 1: 8+ karakter, 1 huruf besar, 1 angka. Strength 2: + 1 karakter spesial |
| Not Empty | FormValidator.notEmpty() |
.notEmpty() |
Tidak boleh kosong |
| Min Length | FormValidator.minLength(5) |
.minLength(5) |
Panjang string minimum |
| Max Length | FormValidator.maxLength(100) |
.maxLength(100) |
Panjang string maksimum |
| Min Value | FormValidator.minValue(18) |
.minValue(18) |
Nilai numerik minimum (juga bekerja pada panjang string, panjang list, panjang map) |
| Max Value | FormValidator.maxValue(100) |
.maxValue(100) |
Nilai numerik maksimum |
| Min Size | FormValidator.minSize(2) |
.minSize(2) |
Ukuran minimum untuk list/string |
| Max Size | FormValidator.maxSize(5) |
.maxSize(5) |
Ukuran maksimum untuk list/string |
| Contains | FormValidator.contains(['a', 'b']) |
.contains(['a', 'b']) |
Nilai harus mengandung salah satu dari nilai yang diberikan |
| Begins With | FormValidator.beginsWith("https://") |
.beginsWith("https://") |
String harus dimulai dengan prefix |
| Ends With | FormValidator.endsWith(".com") |
.endsWith(".com") |
String harus diakhiri dengan suffix |
| URL | FormValidator.url() |
.url() |
Memvalidasi format URL |
| Numeric | FormValidator.numeric() |
.numeric() |
Harus berupa angka |
| Boolean True | FormValidator.booleanTrue() |
.booleanTrue() |
Harus true |
| Boolean False | FormValidator.booleanFalse() |
.booleanFalse() |
Harus false |
| Date | FormValidator.date() |
.date() |
Harus tanggal yang valid |
| Date In Past | FormValidator.dateInPast() |
.dateInPast() |
Tanggal harus di masa lalu |
| Date In Future | FormValidator.dateInFuture() |
.dateInFuture() |
Tanggal harus di masa depan |
| Age Is Older | FormValidator.dateAgeIsOlder(18) |
.dateAgeIsOlder(18) |
Usia harus lebih tua dari N |
| Age Is Younger | FormValidator.dateAgeIsYounger(65) |
.dateAgeIsYounger(65) |
Usia harus lebih muda dari N |
| Capitalized | FormValidator.capitalized() |
.capitalized() |
Huruf pertama harus huruf besar |
| Lowercase | FormValidator.lowercase() |
.lowercase() |
Semua karakter harus huruf kecil |
| Uppercase | FormValidator.uppercase() |
.uppercase() |
Semua karakter harus huruf besar |
| Phone US | FormValidator.phoneNumberUs() |
.phoneNumberUs() |
Format nomor telepon AS |
| Phone UK | FormValidator.phoneNumberUk() |
.phoneNumberUk() |
Format nomor telepon UK |
| Zipcode US | FormValidator.zipcodeUs() |
.zipcodeUs() |
Format zipcode AS |
| Postcode UK | FormValidator.postcodeUk() |
.postcodeUk() |
Format postcode UK |
| Regex | FormValidator.regex(r'pattern') |
.regex(r'pattern') |
Harus cocok dengan pola regex |
| Equals | — | .equals(otherValue) |
Harus sama dengan nilai lain |
| Custom | FormValidator.custom(validate: fn) |
.custom(validate: fn) |
Fungsi validasi kustom |
Semua aturan menerima parameter message opsional untuk menyesuaikan pesan error.
Membuat Aturan Validasi Kustom
Untuk membuat aturan validasi yang dapat digunakan kembali, extend class FormRule:
class FormRuleUsername extends FormRule {
@override
String? rule = "username";
@override
String? message = "The {{attribute}} must be a valid username.";
FormRuleUsername({String? message}) {
if (message != null) {
this.message = message;
}
}
@override
bool validate(data) {
if (data is! String) return false;
// Username: alphanumeric, underscores, 3-20 chars
return RegExp(r'^[a-zA-Z0-9_]{3,20}$').hasMatch(data);
}
}
Gunakan {{attribute}} sebagai placeholder di message -- akan diganti dengan label field saat runtime.
Menggunakan FormRule Kustom
Tambahkan aturan kustom Anda ke FormValidator menggunakan FormValidator.rule():
FormValidator validator = FormValidator.rule([
FormRuleNotEmpty(),
FormRuleUsername(),
]);
FormValidationResult result = validator.check("my_username");
Atau gunakan metode .custom() untuk aturan sekali pakai tanpa membuat class:
FormValidator()
.notEmpty()
.custom(
message: "Username must start with a letter",
validate: (data) => RegExp(r'^[a-zA-Z]').hasMatch(data.toString()),
)