เนื้อหาต่อไปนี้ จะมาดูต่อเกี่ยวกับการใช้งานฟอร์ม ต่อจาก
เนื้อหาตอนที่แล้ว ที่เราพูดถึงเกี่ยวกับการใช้งาน TextFormField
เป็นส่วนใหญ่ ยังมี widget เพิ่มเติมที่ใช้งามร่วมกับฟอร์ม รวมไปถึง
การจัดการกับข้อมูลที่ได้จากฟอร์ม เพื่อนำไปใช้งานต่อ
ทบทวนตอนที่แล้วได้ที่บทความ
การใช้งาน Form และ Form Validation ใน Flutter http://niik.in/1048
https://www.ninenik.com/content.php?arti_id=1048 via @ninenik
*เนื้อหานี้ใช้เนื้อหาต่อเนื่องจากบทความ http://niik.in/1048
การใช้งาน Checkbox
เราสามารถกำหนด checkbox ให้กับฟอร์มด้วย 2 widget คือ Checkbox กับ CheckboxListTile
แต่เราจะแนะนำเป็น CheckboxListTile() ที่จะใช้งานได้งายและสะดวกกว่า เพราะเป็นการนำเอา ListTile กับ
Checkbox มารวมกัน สามารถกดที่พื้นที่ของ ListTile หรือข้อความแทนการกดที่ตัว checkbox โดยตรง
สามารถจัดตำแหน่งไม่ว่าจะไว้ด้านหน้าข้อความ หรือด้านหลังข้อความก็ทำได้ง่าย
กำหนด State property ที่เกี่ยวข้อง
1 | bool _termsChecked = false ; |
ดูตัวอย่างการใช้งาน checkbox ทั้งสองแบบ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ListTile( title: Text( 'This is title' ), trailing: Checkbox( value: _termsChecked, onChanged: (bool? value) { setState(() { _termsChecked = value!; }); }, ), ), CheckboxListTile( value: _termsChecked, onChanged: (value) { setState(() { _termsChecked = value!; }); }, subtitle: !_termsChecked ? Text( 'Required' , style: TextStyle(color: Colors.red, fontSize: 12.0), ) : null , title: new Text( 'I agree to the terms and condition' , ), controlAffinity: ListTileControlAffinity.leading, ), |
ผลลัพธ์ที่ได้

ตัวแรกเราต้องจัดรูปแบบใน ListTile อีกที แต่ตัวที่สองเราสามารถใช้งานคล้าย ListTile ได้เลย
ในที่นี้จะพูดถึง CheckboxListTile
ตัว checkbox จะรองรับค่าหรือ value ที่เป็น boolean เวลาเราจะใช้งาน ต้องกำหนดตัวแปร boolean
เพื่อรับค่ามาใช้งาน ใช้สำหรับตอบรับ หรือปฏิเสธในกรณีเงื่อนไขให้เลือก 1 รายการ อย่างในตัวอย่าง
เป็นการให้เลือก ตอบรับ ข้อกำหนดของการใช้งาน
ในกรณีใช้เป็นตัวเลือกหลายๆ รายการ จะหมายถึง ตอบรับกับรายการตัวเลือกนั้นๆ หรือไม่ ดูตัวอย่าง
1 2 3 4 5 6 7 8 9 10 | // กำหนดตัวแปร ลิสรายการ checkbox List<Map<String, bool>> hobbies = [ { 'อ่านหนังสือ' : true }, { 'วาดรูป' : false }, { 'ดูหนัง' : true }, { 'ช้อปปิ้ง' : true }, ]; // กำหนดตัวแปร เก็บค่าของแต่ละ checkbxo List<bool> _checkHobby = []; |
ต่อไปส่วนของการวนลูปแสดงข้อมูล และใช้งาน
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Divider(), // ตัว widget แบ่ง Builder(builder: (context) { // เราใช้ Builder เพื่อที่จะใช้งานฟังก์ชั่นสร้าง widget ได้ List<Widget> list = <Widget>[]; hobbies.asMap().forEach((index, hobby){ // วนลูปสร้างลิสรายการ var key = hobby.keys.toList(); // แปลงเป็น list ของ key var val = hobby.values.toList(); // แปลงเป็น list ของ value _checkHobby.add(val[0]); // เก็บค่า value ขแงแต่ละรายการ list.add(CheckboxListTile( value: _checkHobby[index], // ใช้ค่า value ของแต่ละรายการ onChanged: (value) { setState(() { _checkHobby[index] = value!; // เปลี่ยนค่าเมื่อมีการเลือกหรือไม่เลือก }); }, title: Text( '${key[0]}' , ), controlAffinity: ListTileControlAffinity.leading, )); }); return Column( // คืนค่าเป็นรายการ checkbox ในคอลัมน์ children: list, ); }), |
ผลลัพธ์ที่ได้

กรณีมีตัวเลือกหลายรายการ จะเป็นลักษณะ ว่าแต่ละรายการเราเลือกหรือไม่
การใช้งาน Radio
รูปแบบการใช้งาน radio ร่วมกับฟอร์ม ก็สามารถทำได้คล้ายๆ กับ checkbox โดยเราสามารถใช้ได้ทั้ง
Radio กับ RadioListTile และวิธีการที่สะดวกและง่ายก็แนะนำเป็น RadioListTile
radio จะใช้สำหรับให้เลือกอย่างใดอย่างหนึ่งเพียงอย่างเดียว จากรายการที่แสดงให้เลือก โดยค่าที่กำหนดให้
กับ radio จะเป็น object แตกต่างจาก checkbox ซึ่ง object หรือ class ที่เหมาะจะมาใช้เป็นข้อมูล radio ก็คือ
enum ( มีอธิบายไว้ในบทความ http://niik.in/1044 )
อย่างสมมติเช่น เรากำหนดสีตัวเลือก ให้ผู้ใช้ระบุ ก็จะกำหนดเป็น
1 | enum ColorOption { red, green, blue } |
อย่าลืมว่า enum เป็น class หนึ่ง ดังนั้นเวลาระบุ ก็ต้องกำหนดไว้ด้านนอกของ class อื่นๆ
ปกติจะใช้ radio ในการกำหนดตัวเลือกที่ไม่มากนัก ดูตัวอย่าง การเลือกเพศ ชาย หญิง
สิ่งแรกก็คือกำหนด class หรือ object ของค่าข้อมูลที่จะใช้งาน
1 | enum Gender { male, female } |
จากนั้นเราก็กำหนดตัวแปรค่าเริ่มต้น
1 2 3 4 | // กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก Gender? _selectedGender = Gender.male; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง String? _selectedGenderText = 'ชาย' ; |
เรากำหนดตัวแปรค่าเริ่มต้นสำหรับรายการที่ถูกเลือก และกำหนดตัวแปร
ข้อมูลเพิ่มเติม สำหรับนำไปใช้งาน อย่างข้างต้น ให้ค่าเริ่มต้นเป็น male และข้อความ
ที่สัมพันธ์ก็คือ เพศ 'ชาย'
ตัวอย่างการเรียกใช้งาน RadioListTile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | Column( children: <Widget>[ RadioListTile( title: const Text( 'Male' ), value: Gender.male, // ค่าของตัวเล็อก male groupValue: _selectedGender, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (Gender? value) { setState(() { _selectedGender = value; _selectedGenderText = (_selectedGender == Gender.male) ? 'ชาย' : 'หญิง' ; }); }, controlAffinity: ListTileControlAffinity.leading, ), RadioListTile( title: const Text( 'Female' ), value: Gender.female, // ค่าของตัวเล็อก female groupValue: _selectedGender, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (Gender? value) { setState(() { _selectedGender = value; _selectedGenderText = (_selectedGender == Gender.male) ? 'ชาย' : 'หญิง' ; }); }, controlAffinity: ListTileControlAffinity.leading, ), ], ), |
ผลลัพธ์ที่ได้

ค่าเริ่มต้นที่ถูกเลือกเป็น male เมื่อเรากดปุ่ม submit ก็จะแสดงในส่วนของข้อความที่เรากำหนดไว้ใช้งาน
ให้สัมพันธ์กับข้อมูลที่เลือก
สมมติเราอยากสร้างรายการ radio รองรับจำนวนมากขึ้นมาหน่อย ก็สามารถใช้เป็นแบบนี้ได้
1 | enum ColorOption { red, green, blue } |
จากนั้นเราก็กำหนดตัวแปรค่าเริ่มต้น
1 2 3 4 5 6 | // กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก ColorOption? _selectedColorOption = ColorOption.red; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง String _selectedColorOptionText = 'สีแดง' ; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิงในลูป List<String> _listColorOptionText = [ 'สีแดง' , 'สีเขียว' , 'สีน้ำเงิน' ]; |
ตัวอย่างการเรียกใช้งาน RadioListTile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Divider(), Builder(builder: (context) { List<Widget> list = <Widget>[]; ColorOption.values.asMap().forEach((index, val){ list.add( RadioListTile( title: Text(_listColorOptionText[index]), value: val, // ค่าของตัวเล็อก female groupValue: _selectedColorOption, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (ColorOption? value) { setState(() { _selectedColorOption = value; _selectedColorOptionText = _listColorOptionText[index]; }); }, controlAffinity: ListTileControlAffinity.leading, ), ); }); return Column( children: list, ); }), |
ผลลัพธ์ที่ได้

วิธีนี้เหมาะกับรายการตัวเลือกที่มีจำนวนมากๆ เวลากำหนดก็จะทำได้ง่ายขึ้น กว่าการเพิ่มทีละตัว
การใช้งาน Dropdown
ใช้สำหรับแสดงลิสรายการเพื่อให้ผู้ใช้เลือกหรือกำหนดค่าที่ต้องการ คล้ายกับการเลือกของ radio ที่จะ
สามารถเลือกได้เพียงอันเดียว จากรายการทั้งหมด การใช้งาน DropdownButtonFormField จะรองรับสำหรับ
ฟอร์มมากกว่าการใช้งาน DropdownButton ธรรมดา ดูตัวอย่างทั้งสองรูปแบบ เบื้องต้น
กำหนด State property ที่เกี่ยวข้อง
1 | String _dropdownValue = '' ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | DropdownButton<String>( value: null , onChanged: (String? newValue) { setState(() { _dropdownValue = newValue!; }); }, isExpanded: true , items: <String>[ 'One' , 'Two' , 'Three' , 'Four' ] .map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), SizedBox(height: 5.0,), DropdownButtonFormField<String>( value: null , onChanged: (value) { setState(() { _dropdownValue = value!; }); }, hint: Text( 'Rating' ), isExpanded: true , items: <String>[ 'One' , 'Two' , 'Three' , 'Four' ] .map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), |
ผลลัพธ์ที่ได้

มาดูวิธีการกำหนดและใช้งานสำหรับฟอร์ม
1 2 3 4 | // กำหนดตัวแปรสำหรับลิสรายการ List<String> maritalStatus = [ 'โสด' , 'แต่งงาน' , 'หย่า' , 'หม้าย' ]; // กำหนดตัวแปรสำหรับเก็บค่าที่เลือก เริ่มต้นเป็นค่าว่าง String _seslectedMaritalStatus = '' ; |
ต่อไปเรียกใช้งานเป็นดังนี้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Divider(), DropdownButtonFormField<String>( value: null , autovalidateMode: AutovalidateMode.always, // validator: (value) => (value == null) ? 'เลือกสถานะการแต่งงาน' : null, validator: Validators.required( 'เลือกสถานะการแต่งงาน' ), onChanged: (value) { setState(() { _seslectedMaritalStatus = value!; }); }, hint: Text( 'สถานะการแต่งงาน' ), isExpanded: true , items: maritalStatus.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), |
ผลลัพธ์ที่ได้

จะเห็นว่า DropdownButtonFormField รองรับการตรวจสอบข้อมูลด้วย validator เหมือนกับ TextFormField
เราสามารถสร้าง List<String> เพื่อวนลูปสร้างรายการตัวเลือกให้กับ dropbox ได้ง่าย
ตอนนี้เราได้รู้จัก element ที่ใช้งานร่วมกับฟอร์มเพิ่มเติม รวมถึง TextFormFiled จากบทความตอนที่แล้ว เราได้
รู้จักวิธีการสร้างลิสรายการสำหรับแต่ละ widget รู้จักกำหนดตัวแปรสำหรับรับค่าเพื่อนำไปใช้งานต่อ
เราจะลองสร้างฟอร์มสมมติ โดยรวม element ต่างๆ มาไว้ด้วยกันในฟอร์ม ตามตัวอย่างข้างล่าง และรูปแบบการ
กำหนดสำหรับเป็นข้อมูลของฟอร์ม เมื่อกดส่งข้อมูล จะจำลองการแสดงข้อมูลที่เป็น Map
ไฟล์ contact.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | import 'package:flutter/material.dart' ; import 'package:intl/date_symbol_data_local.dart' ; import 'package:intl/intl.dart' ; import 'package:flutter/services.dart' ; import '../validations/validation.dart' ; class Contact extends StatefulWidget { static const routeName = '/contact' ; const Contact({Key? key}) : super (key: key); @override State<StatefulWidget> createState() { return _ContactState(); } } class _ContactState extends State<Contact> with Validators { // กำหนดข้อมูลฟิลด์ สำหรับบันทึก final Map<String, dynamic> formData = { 'email' : null , 'password' : null , 'birthday' : null , 'gender' : null , 'hobby' : null , 'maritalstatus' : null , }; // สร้างฟอร์ม key หรือ id ของฟอร์มสำหรับอ้างอิง final _formKey = GlobalKey<FormState>(); late DateFormat dateFormat; // รูปแบบการจัดการวันที่และเวลา // กำหนดตัวแปรรับค่า final _text1 = TextEditingController(); final _text2 = TextEditingController(); final _text3 = TextEditingController(); final _text4 = TextEditingController(); // กำหนดตัวแปร ลิสรายการ checkbox List<Map<String, bool>> hobbies = [ { 'อ่านหนังสือ' : true }, { 'วาดรูป' : false }, { 'ดูหนัง' : true }, { 'ช้อปปิ้ง' : true }, ]; // กำหนดตัวแปร เก็บค่าของแต่ละ checkbxo List<bool> _checkHobby = []; List<String> _checkedHobby = []; // ค่าสำหรับส่งไปใช้งาน // กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก Gender? _selectedGender = Gender.male; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง String? _selectedGenderText = 'ชาย' ; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิงในลูป List<String> _listGenderText = [ 'ชาย' , 'หญิง' ]; // กำหนดตัวแปรสำหรับลิสรายการ List<String> maritalStatus = [ 'โสด' , 'แต่งงาน' , 'หย่า' , 'หม้าย' ]; // กำหนดตัวแปรสำหรับเก็บค่าที่เลือก เริ่มต้นเป็นค่าว่าง String _seslectedMaritalStatus = '' ; // กำหนดสถานะการแสดงแบบรหัสผ่าน bool _isHidden = true ; bool _termsChecked = false ; void _selectDate() async { final DateTime now = DateTime.now(); final DateTime firstDate = DateTime(2017, 7, 1); // ช่วงเริ่มต้น final DateTime lastDate = DateTime(2023, 7, 1); // ช่วงสิ้นสิน final DateTime initialDate = now.isAfter(lastDate) ? lastDate : now; final DateTime? newDate = await showDatePicker( context: context, initialDate: initialDate, firstDate: firstDate, lastDate: lastDate, helpText: 'Select a date' , ); if (newDate != null ) { setState(() { _text2.value = TextEditingValue(text: dateFormat.format(newDate).toString()); }); } } // เกียวกับการใช้เวลา /// แปลงเวลาจากวันที่ TimeOfDay.fromDateTime(DateTime.now()) /// เวลาปัจจุบัน TimeOfDay.now() /// แบบกำหนดเอง TimeOfDay(hour: 7, minute: 15), void _selectTime() async { final TimeOfDay? newTime = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (newTime != null ) { setState(() { _text2.value = TextEditingValue(text: newTime.format(context)); }); } } @override void initState() { super .initState(); // กำหนดรูปแบบการจัดการวันที่และเวลา Intl.defaultLocale = 'en' ; initializeDateFormatting(); dateFormat = DateFormat( 'd/MM/y' , 'en' ); } @override void dispose() { _text1.dispose(); // ยกเลิกการใช้งานที่เกี่ยวข้องทั้งหมดถ้ามี _text2.dispose(); _text3.dispose(); _text4.dispose(); super .dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( 'Contact Us' ), ), body: SingleChildScrollView( child: Form( // ใช้งาน Form key: _formKey, // กำหนด key child: Padding( padding: const EdgeInsets.all(10.0), child: Column( children: <Widget>[ // กำหนด widget ที่จะใช้งานกับฟอร์ม TextFormField( autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( hintText: 'อีเมล' , icon: Icon(Icons.email_outlined), ), controller: _text1, // ผูกกับ TextFormField ที่จะใช้ validator: Validators.compose([ Validators.required( 'กรุณาระบุอีเมล' ), Validators.email( 'กรุณาใส่อีเมลให้ถูกต้อง' ) ]), ), SizedBox(height: 5.0,), TextFormField( autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( icon: Icon(Icons.vpn_key), hintText: 'รหัสผ่าน' , suffixIcon: IconButton( onPressed: (){ setState(() { _isHidden = !_isHidden; // เมื่อกดก็เปลี่ยนค่าตรงกันข้าม }); }, icon: Icon( _isHidden // เงื่อนไขการสลับ icon ? Icons.visibility_off : Icons.visibility ), ), ), controller: _text3, // ผูกกับ TextFormField ที่จะใช้ validator: Validators.required( 'กรุณาระบุรห้สผ่าน' ), obscureText: _isHidden, // การซ่อนหรือแสดงข้อความในรูปแบบรหัสผ่าน ), SizedBox(height: 5.0,), TextFormField( autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( hintText: 'วันเกิด' , icon: Icon(Icons.date_range), ), controller: _text2, // ผูกกับ TextFormField ที่จะใช้ validator: Validators.required( 'กรุณาระบุวันเกิด' ), onTap: _selectDate, readOnly: true , ), Divider(), Builder(builder: (context) { List<Widget> list = <Widget>[]; Gender.values.asMap().forEach((index, val){ list.add( RadioListTile( title: Text(_listGenderText[index]), value: val, // ค่าของตัวเล็อก female groupValue: _selectedGender, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (Gender? value) { setState(() { _selectedGender = value; _selectedGenderText = _listGenderText[index]; }); }, controlAffinity: ListTileControlAffinity.leading, ), ); }); return Column( children: list, ); }), Divider(), // ตัว widget แบ่ง Builder(builder: (context) { // เราใช้ Builder เพื่อที่จะใช้งานฟังก์ชั่นสร้าง widget ได้ List<Widget> list = <Widget>[]; _checkedHobby.clear(); hobbies.asMap().forEach((index, hobby){ // วนลูปสร้างลิสรายการ var key = hobby.keys.toList(); // แปลงเป็น list ของ key var val = hobby.values.toList(); // แปลงเป็น list ของ value _checkHobby.add(val[0]); // เก็บค่า value ขแงแต่ละรายการ if (_checkHobby[index]) _checkedHobby.add(key[0]); // เก็บรายการที่เลือก list.add(CheckboxListTile( value: _checkHobby[index], // ใช้ค่า value ของแต่ละรายการ onChanged: (value) { setState(() { _checkHobby[index] = value!; // เปลี่ยนค่าเมื่อมีการเลือกหรือไม่เลือก }); }, title: Text( '${key[0]}' , ), controlAffinity: ListTileControlAffinity.leading, )); }); return Column( // คืนค่าเป็นรายการ checkbox ในคอลัมน์ children: list, ); }), Divider(), DropdownButtonFormField<String>( value: null , autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( icon: Icon(Icons.family_restroom_outlined), ), validator: Validators.required( 'เลือกสถานะการแต่งงาน' ), onChanged: (value) { setState(() { _seslectedMaritalStatus = value!; }); }, hint: Text( 'สถานะการแต่งงาน' ), isExpanded: true , items: maritalStatus.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), Divider(), CheckboxListTile( value: _termsChecked, onChanged: (value) { setState(() { _termsChecked = value!; }); }, subtitle: !_termsChecked ? Text( 'ต้องระบุ' , style: TextStyle(color: Colors.red, fontSize: 12.0), ) : null , title: new Text( 'ยอมรับเงื่อนไขและข้อตกลงการใช้งาน' , ), controlAffinity: ListTileControlAffinity.leading, ), ElevatedButton( onPressed: () { // อ้างอิงฟอร์มที่กำลังใช้งาน ตรวจสอบความถูกต้องข้อมูลในฟอร์ม if (_formKey.currentState!.validate()) { //หากผ่าน formData[ 'email' ] = _text1.text; formData[ 'password' ] = _text2.text; formData[ 'birthday' ] = _text3.text; formData[ 'gender' ] = _selectedGenderText; formData[ 'hobby' ] = _checkedHobby; formData[ 'maritalstatus' ] = _seslectedMaritalStatus; // print(formData); // แสดงข้อความจำลอง ใน snackbar ScaffoldMessenger.of(context).showSnackBar( // นำค่าข้อมูลไปแสดงหรือใช้งานผ่าน controller SnackBar(content: Text( 'Process Data...${formData}' )), ); } }, child: const Text( 'Submit' ), ), ], ), ), ), ), ); } } // กำหนดข้อมูลสำหรับ radio enum Gender { male, female } |
ผลลัพธ์ที่ได้

เมื่อทำการ submit หรือ validate ฟอร์มผ่านแล้ว เราทำการเก็บค่าข้อมูลทั้งหมด ไว้ใน Map ที่ชื่อ
formData เพื่อนำไปใช้งานต่อ ข้างต้น เราแค่แสดงผลข้อมูลด้วย snackBar
สำหรับเนื้อหาเกี่ยวกับการใช้งาน element ของฟอร์มเพิ่มเติมในตอนนี้ก็มีประมาณนี้ หวังว่าจะเป็แแนวทาง
นำไปปรับใช้งานต่อไป เนื้อหาตอนหน้า เราจะนำสิ่งที่ได้เรียนรู้เกี่ยวกับฟอร์มทั้งสองตอนนี้ ไปประยุกต์
กับการใช้งานฟอร์มที่บันทึกลงฐานข้อมูลหนังสือของบทความก่อนหน้า รอติดตาม