Kodokon kodokon.com

फ़ॉर्म: TextField, कंट्रोलर और वैलिडेशन

TextEditingController से अपने इनपुट फ़ील्ड को नियंत्रित करें और Form तथा TextFormField की बदौलत हर प्रविष्टि को एक साथ वैलिडेट करें।

9 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

बिना कंट्रोलर वाला इनपुट फ़ील्ड एक ब्लैक बॉक्स है। TextEditingController आपको नियंत्रण देता है: किसी भी क्षण controller.text पढ़ें, फ़ील्ड को पहले से भरें, सबमिशन के बाद उसे खाली करें, या addListener से हर कीस्ट्रोक सुनें। कंट्रोलर को एक State में बनाया जाता है, कभी build में नहीं - वरना हर रीबिल्ड पर यह फिर से बन जाएगा।

DART
import 'package:flutter/material.dart';

class NicknameField extends StatefulWidget {
  const NicknameField({super.key});

  @override
  State<NicknameField> createState() =>
      _NicknameFieldState();
}

class _NicknameFieldState extends State<NicknameField> {
  final _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _controller,
      decoration: const InputDecoration(
        labelText: 'Nickname',
        border: OutlineInputBorder(),
      ),
      onSubmitted: (value) => debugPrint(value),
    );
  }
}
कंट्रोलर State में रहता है और dispose() में समाप्त होता है।

जैसे ही किसी स्क्रीन पर जाँचने के लिए कई फ़ील्ड हों, तिकड़ी Form, GlobalKey<FormState> और TextFormField को अपनाएँ। हर फ़ील्ड अपना नियम validator में बताता है: फ़ंक्शन एक त्रुटि संदेश लौटाता है, या यदि सब ठीक है तो null। की (key) पर validate() का एक कॉल एक साथ सभी वैलिडेटर को ट्रिगर करता है।

DART
import 'package:flutter/material.dart';

class SignUpForm extends StatefulWidget {
  const SignUpForm({super.key});

  @override
  State<SignUpForm> createState() => _SignUpFormState();
}

class _SignUpFormState extends State<SignUpForm> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();

  @override
  void dispose() {
    _emailController.dispose();
    super.dispose();
  }

  void _submit() {
    if (_formKey.currentState!.validate()) {
      debugPrint('Email: ${_emailController.text}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextFormField(
            controller: _emailController,
            keyboardType: TextInputType.emailAddress,
            decoration: const InputDecoration(
              labelText: 'Email',
            ),
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Required field';
              }
              if (!value.contains('@')) {
                return 'Invalid address';
              }
              return null;
            },
          ),
          const SizedBox(height: 16),
          FilledButton(
            onPressed: _submit,
            child: const Text('Create account'),
          ),
        ],
      ),
    );
  }
}
validate() फ़ॉर्म के हर वैलिडेटर को ट्रिगर करता है।

जब बटन क्लिक किया जाता है, validate() हर validator को चलाता है: लौटाए गए संदेश संबंधित फ़ील्ड के नीचे लाल रंग में दिखते हैं, और यदि कम से कम एक फ़ील्ड अमान्य है तो मेथड false लौटाता है। इसलिए आपका सबमिशन तर्क एक अकेले if के पीछे रहता है - अमान्य डेटा सबमिट करना असंभव है।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. TextEditingController किस लिए होता है?
    • फ़ील्ड की सीमा (border) बनाने के लिए
    • फ़ील्ड के टेक्स्ट को पढ़ने और बदलने के लिए, और उसके बदलावों को सुनने के लिए
    • ईमेल पते को अपने आप वैलिडेट करने के लिए
    • कीबोर्ड को बंद करने के लिए
  2. जब वैल्यू मान्य हो, तब एक validator को क्या लौटाना चाहिए?
    • true
    • एक खाली स्ट्रिंग
    • null
    • वैल्यू खुद
  3. State के dispose() मेथड में _controller.dispose() को क्यों कॉल करें?
    • स्क्रीन पर फ़ील्ड को खाली करने के लिए
    • संसाधनों को मुक्त करने और मेमोरी लीक से बचने के लिए
    • फ़ॉर्म सबमिट करने के लिए