- vừa được xem lúc

Làm việc với Form & Kiểm tra dữ liệu nhập (Validation) trong Flutter

0 0 2

Người đăng: Coder Tập Sự

Theo Viblo Asia

Hôm nay, chúng ta sẽ làm quen với Form – giúp gom nhiều TextField lại với nhau và kiểm tra dữ liệu trước khi lưu hay gửi.

🎯 Mục tiêu hôm nay

  • Sử dụng widget FormTextFormField
  • Kiểm tra dữ liệu nhập (validation)
  • Kết hợp nhiều trường nhập trong cùng một form

TextField vs TextFormField – Khác nhau gì?

Trước khi bắt đầu với Form, chúng ta cần phân biệt một chút giữa hai widget nhập liệu trong Flutter:

Đặc điểm TextField TextFormField
Dùng để Nhập dữ liệu đơn lẻ Nhập dữ liệu trong một Form
Hỗ trợ validation ❌ Không hỗ trợ sẵn ✅ Có thể dùng validator dễ dàng
Thường dùng khi... Chỉ cần nhập liệu không cần kiểm tra Khi cần kiểm tra dữ liệu (form đăng ký...)
Kết hợp với Form Không Được thiết kế để dùng với Form

Ví dụ:

// TextField – không có validate
TextField( controller: _nameController, decoration: InputDecoration(labelText: 'Tên'),
); // TextFormField – có thể validate
TextFormField( controller: _nameController, decoration: InputDecoration(labelText: 'Tên'), validator: (value) { if (value == null || value.isEmpty) { return 'Vui lòng nhập tên'; } return null; },
);

➡️ Nói ngắn gọn: Khi chúng ta cần kiểm tra dữ liệu người dùng nhập, hãy dùng TextFormField trong Form. Còn nếu chỉ nhập đơn giản (ví dụ ô tìm kiếm), thì TextField là đủ.

Thực hành: Tạo form đăng ký đơn giản

Chúng ta sẽ xây dựng một form với 2 ô nhập:

  • Tên người dùng (bắt buộc nhập)
  • Email (bắt buộc nhập và phải đúng định dạng email)

Khi bấm nút "Đăng ký", nếu hợp lệ thì hiển thị thông báo đăng ký thành công.

import 'package:flutter/material.dart'; class SimpleFormExample extends StatefulWidget {  _SimpleFormExampleState createState() => _SimpleFormExampleState();
} class _SimpleFormExampleState extends State<SimpleFormExample> { final _formKey = GlobalKey<FormState>(); final TextEditingController _nameController = TextEditingController(); final TextEditingController _emailController = TextEditingController();  void dispose() { _nameController.dispose(); _emailController.dispose(); super.dispose(); } void _submitForm() { if (_formKey.currentState!.validate()) { final name = _nameController.text; showDialog( context: context, builder: (_) => AlertDialog( content: Text('Chào mừng $name! Đăng ký thành công 🎉'), ), ); } }  Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Form Đăng ký')), body: Padding( padding: const EdgeInsets.all(20), child: Form( key: _formKey, child: Column( children: [ TextFormField( controller: _nameController, decoration: InputDecoration(labelText: 'Tên'), validator: (value) { if (value == null || value.isEmpty) { return 'Vui lòng nhập tên'; } return null; }, ), SizedBox(height: 16), TextFormField( controller: _emailController, decoration: InputDecoration(labelText: 'Email'), validator: (value) { if (value == null || value.isEmpty) { return 'Vui lòng nhập email'; } final emailRegex = RegExp(r'^[^@]+@[^@]+\.[^@]+'); if (!emailRegex.hasMatch(value)) { return 'Email không hợp lệ'; } return null; }, ), SizedBox(height: 24), ElevatedButton( onPressed: _submitForm, child: Text('Đăng ký'), ), ], ), ), ), ); }
}
  • TextFormField nên được gói bên trong Form để quản lý dữ liệu hiệu quả.
  • Mỗi ô nhập có thể có validator để kiểm tra nội dung.
  • GlobalKey<FormState> giúp truy cập và kiểm tra toàn bộ trạng thái của form, ví dụ như validate().

Trong các ứng dụng thực tế, form có thể phức tạp hơn nhiều với nhiều trường nhập và các loại validation khác nhau. Chúng ta cũng có thể tùy chỉnh giao diện thông báo lỗi để phù hợp với thiết kế của ứng dụng bằng cách sử dụng thuộc tính errorText trong InputDecoration.

Lời kết

Qua bài học ngày hôm nay, chúng ta đã biết cách sử dụng Form và TextFormField để kiểm tra dữ liệu người dùng nhập vào. Điều này cực kỳ quan trọng khi xây dựng các form đăng ký, đăng nhập, liên hệ... Sắp tới, mình sẽ thử làm một mini app có sử dụng form, để luyện tập thực tế luôn 😄

Lời cuối bài xin cảm ơn mọi người đã đọc đến đây! Nếu mọi người cũng đang tìm hiểu Flutter thì mình chúc chúng ta kiên trì và vững bước mỗi ngày. Hẹn gặp lại mọi người ở bài viết ngày mai nhé! ✌️🚀

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 1: Làm quen cô nàng Flutter

Lời mở đầu. Gần đây, Flutter nổi lên và được Google PR như một xu thế của lập trình di động vậy.

0 0 299

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 3: Lột trần cô nàng Flutter, BuildContext là gì?

Lời mở đầu. Màn làm quen cô nàng FLutter ở Phần 1 đã gieo rắc vào đầu chúng ta quá nhiều điều bí ẩn về nàng Flutter.

1 1 355

- vừa được xem lúc

Dart Cheat Sheet - Full bộ "bỏ túi" các syntax trong ngôn ngữ Dart

Dart là một ngôn ngữ mới dùng cho cả Mobile và Web với Flutter Framework, thậm chí dùng cho Backend. Để giúp mọi người dễ dàng nắm bắt ngôn ngữ này hơn, 200lab Education đã tổng hợp thành bộ "bí tịch" dưới đây để tra cứu nhanh, tăng tốc phát triển phần mềm.

0 0 54

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 2: StatefulWidget vs StatelessWidget. Khi nào thì cần sử dụng cái nào?

Lời mở đầu. Ở bài trước, chúng ta đã dừng lại ở một kết thúc mở.

0 0 102

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 4: Lột trần InheritedWidget

Lời mở đầu. Trong đoạn kết của phần 2, chúng ta đã đối mặt với 1 bài toán: Làm thế nào để truyền data từ một widget cha nào đó xuống thẳng widget chắt mà không phải sử dụng constructor để truyền xuống

0 0 71

- vừa được xem lúc

Chinh phục RxDart Flutter trong 3 nốt nhạc. Nốt thứ nhất: Stream và giải thích các thuật ngữ

Lời mở đầu. Mình viết series này với mục đích chia sẻ kiến thức về RxDart trong Flutter.

0 0 80