ด้วยสํานึกในพระมหากรุณาธิคุณสมเด็จพระนางเจ้าสิริกิติ์เป็นล้นพ้นอันหาที่สุดมิได้
ด้วยสํานึกในพระมหากรุณาธิคุณสมเด็จพระนางเจ้าสิริกิติ์เป็นล้นพ้นอันหาที่สุดมิได้


การจัดการข้อมูลของ Form Element อื่นๆ ใน Flutter

เขียนเมื่อ 4 ปีก่อน โดย Ninenik Narkdee
checkboxlisttile dropdownbuttonformfield radiolisttile flutter

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ checkboxlisttile dropdownbuttonformfield radiolisttile flutter

ปัจจุบัน นักพัฒนาสามารถ ใช้ ChatGPT | Gemini | Claude | Perplexity | Deepseek ช่วยในการแก้ไขปัญหาต่างๆ ในการเขียนโปรแกรม หรือหาข้อมูลเพิ่มเติมได้ง่ายและสะดวก แนะนำให้ทุกคนใช้งานเพื่อพัฒนาศักยภาพของตัวเอง

ดูแล้ว 6,687 ครั้ง




เนื้อหาต่อไปนี้ จะมาดูต่อเกี่ยวกับการใช้งานฟอร์ม ต่อจาก
เนื้อหาตอนที่แล้ว ที่เราพูดถึงเกี่ยวกับการใช้งาน TextFormField
เป็นส่วนใหญ่ ยังมี widget เพิ่มเติมที่ใช้งามร่วมกับฟอร์ม รวมไปถึง
การจัดการกับข้อมูลที่ได้จากฟอร์ม เพื่อนำไปใช้งานต่อ
ทบทวนตอนที่แล้วได้ที่บทความ
    การใช้งาน Form และ Form Validation ใน Flutter http://niik.in/1048
 
   *เนื้อหานี้ใช้เนื้อหาต่อเนื่องจากบทความ http://niik.in/1048
 
 

การใช้งาน Checkbox

    เราสามารถกำหนด checkbox ให้กับฟอร์มด้วย 2 widget คือ Checkbox กับ CheckboxListTile
แต่เราจะแนะนำเป็น CheckboxListTile() ที่จะใช้งานได้งายและสะดวกกว่า เพราะเป็นการนำเอา ListTile กับ
Checkbox มารวมกัน สามารถกดที่พื้นที่ของ ListTile หรือข้อความแทนการกดที่ตัว checkbox โดยตรง
สามารถจัดตำแหน่งไม่ว่าจะไว้ด้านหน้าข้อความ หรือด้านหลังข้อความก็ทำได้ง่าย
 
กำหนด State property ที่เกี่ยวข้อง
    bool _termsChecked = false;    
 
    ดูตัวอย่างการใช้งาน checkbox ทั้งสองแบบ
 
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 รายการ อย่างในตัวอย่าง 
เป็นการให้เลือก ตอบรับ ข้อกำหนดของการใช้งาน
    ในกรณีใช้เป็นตัวเลือกหลายๆ รายการ จะหมายถึง ตอบรับกับรายการตัวเลือกนั้นๆ หรือไม่ ดูตัวอย่าง
 
// กำหนดตัวแปร ลิสรายการ checkbox
List<Map<String, bool>> hobbies = [
  {'อ่านหนังสือ': true},
  {'วาดรูป': false},
  {'ดูหนัง': true},
  {'ช้อปปิ้ง': true},
];

// กำหนดตัวแปร เก็บค่าของแต่ละ checkbxo
List<bool> _checkHobby = [];
 
    ต่อไปส่วนของการวนลูปแสดงข้อมูล และใช้งาน
 
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 )
    อย่างสมมติเช่น เรากำหนดสีตัวเลือก ให้ผู้ใช้ระบุ ก็จะกำหนดเป็น
 
enum ColorOption { red, green, blue }
 
    อย่าลืมว่า enum เป็น class หนึ่ง ดังนั้นเวลาระบุ ก็ต้องกำหนดไว้ด้านนอกของ class อื่นๆ
 
    ปกติจะใช้ radio ในการกำหนดตัวเลือกที่ไม่มากนัก  ดูตัวอย่าง การเลือกเพศ ชาย หญิง
    สิ่งแรกก็คือกำหนด class หรือ object ของค่าข้อมูลที่จะใช้งาน
 
enum Gender { male, female }
 
    จากนั้นเราก็กำหนดตัวแปรค่าเริ่มต้น
 
// กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก
Gender? _selectedGender = Gender.male;
// กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง
String? _selectedGenderText = 'ชาย';
 
    เรากำหนดตัวแปรค่าเริ่มต้นสำหรับรายการที่ถูกเลือก และกำหนดตัวแปร
ข้อมูลเพิ่มเติม สำหรับนำไปใช้งาน อย่างข้างต้น ให้ค่าเริ่มต้นเป็น male และข้อความ
ที่สัมพันธ์ก็คือ เพศ 'ชาย'
 
    ตัวอย่างการเรียกใช้งาน RadioListTile
 
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 รองรับจำนวนมากขึ้นมาหน่อย ก็สามารถใช้เป็นแบบนี้ได้ 
 
enum ColorOption { red, green, blue }
 
    จากนั้นเราก็กำหนดตัวแปรค่าเริ่มต้น
 
// กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก
ColorOption? _selectedColorOption = ColorOption.red;
// กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง
String _selectedColorOptionText = 'สีแดง';
// กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิงในลูป
List<String> _listColorOptionText = ['สีแดง', 'สีเขียว', 'สีน้ำเงิน'];
 
    ตัวอย่างการเรียกใช้งาน RadioListTile
 
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 ที่เกี่ยวข้อง
    String _dropdownValue = '';    
 
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(),  
), 
 
    ผลลัพธ์ที่ได้
 


 
 
    มาดูวิธีการกำหนดและใช้งานสำหรับฟอร์ม 
 
// กำหนดตัวแปรสำหรับลิสรายการ
List<String> maritalStatus = ['โสด','แต่งงาน','หย่า','หม้าย'];
// กำหนดตัวแปรสำหรับเก็บค่าที่เลือก เริ่มต้นเป็นค่าว่าง
String _seslectedMaritalStatus = '';
 
     ต่อไปเรียกใช้งานเป็นดังนี้
 
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

 
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 ของฟอร์มเพิ่มเติมในตอนนี้ก็มีประมาณนี้ หวังว่าจะเป็แแนวทาง
นำไปปรับใช้งานต่อไป เนื้อหาตอนหน้า เราจะนำสิ่งที่ได้เรียนรู้เกี่ยวกับฟอร์มทั้งสองตอนนี้ ไปประยุกต์
กับการใช้งานฟอร์มที่บันทึกลงฐานข้อมูลหนังสือของบทความก่อนหน้า รอติดตาม


   เพิ่มเติมเนื้อหา ครั้งที่ 1 วันที่ 29-07-2024


ดาวน์โหลดโค้ดตัวอย่าง สามารถนำไปประยุกต์ หรือ run ทดสอบได้

http://niik.in/download/flutter/demo_023_29072024_source.rar





อ่านต่อที่บทความ



ทบทวนบทความที่แล้ว









เนื้อหาที่เกี่ยวข้อง









URL สำหรับอ้างอิง








เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ