Home > other >  Pass data to custom stateful widget and return validation staus form
Pass data to custom stateful widget and return validation staus form

Time:02-08

I have created a custom stateful widget. I need to use this same widget multiple times in a form. The their are several different forms accessing the same widget. In order to avoid code duplication I extracted the widget

The only thing that changes in the widget is its label (e.g. Instrument Clean), the hint for the TextFormField (e.g. Instrument clean remark) and the TextEdittingController.

The TextFormField is only writable when Not Okay is selected. Proper validation have been implemented for the same.

My question is how to send label text, hint text and TextEdittingController to this custom Widget and at the same time how to return validation return status to main form.

Code :

class ToogleRemarkWidget extends StatefulWidget {
  final TextEditingController textController;
  const ToogleRemarkWidget({required this.textController, Key? key})
      : super(key: key);
  @override
  State<ToogleRemarkWidget> createState() => _ToogleRemarkWidgetState();
}

class _ToogleRemarkWidgetState extends State<ToogleRemarkWidget> {
  final TextEditingController _textController = TextEditingController();
  int _toggleIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      mainAxisSize: MainAxisSize.max,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        const Expanded(
          flex: 2,
          child: Text('Instrument Clean : '),
        ),
        Expanded(
          flex: 3,
          child: Center(
            child: ToggleSwitch(
              totalSwitches: 2,
              initialLabelIndex: _toggleIndex,
              labels: const ['Okay', 'Not Okay'],
              //TODO Change Okay Icon
              activeBgColors: const [
                [Colors.green],
                [Colors.red]
              ],
              minWidth: 100.0,
              animate: true,
              onToggle: (index) {
                if (index == 0) {
                  _textController.clear();
                }
                setState(() {
                  _toggleIndex = index;
                });
              },
              cornerRadius: 20.0,
            ),
          ),
        ),
        Expanded(
          flex: 5,
          child: TextFormField(
            enabled: _toggleIndex == 0 ? false : true,
            controller: _textController,
            decoration: const InputDecoration(
              icon: Icon(Icons.note_add),
              label: Text('Instrument Clean Remark'),
              hintText: 'Enter Instrument Clean Remark',
              border: OutlineInputBorder(),
            ),
            validator: (value) {
              if (_toggleIndex == 1 && (value == null || value.isEmpty)) {
                return 'Please enter Instrument Cleaned By'; //Validation error
              }
              return null; //Validation Success
            },
          ),
        ),
      ],
    );
  }
}

enter image description here

CodePudding user response:

You need to add the fields to your Stateful Widget and then add a callback function I believe. It should look similar to this. Let me know if this works for you:

import 'package:flutter/material.dart';
class ToogleRemarkWidget extends StatefulWidget {
  final TextEditingController textController;
  final String label_text;
  final String hint_text;
  final Function(String) callback; // Assuming it is a string
  const ToogleRemarkWidget(
      {required this.textController,
      Key? key,
      required this.label_text,
      required this.hint_text,
      required this.callback})
      : super(key: key);
    @override
  State<ToogleRemarkWidget> createState() => _ToogleRemarkWidgetState();
}

To create one I believe it should be like this:

ToogleRemarkWidget(textController: textController, label_text:'label text', hint_text: 'hint text', callback: callbackFunction);

CodePudding user response:

I solved the problem defining all necessary fields in primary StatefulWidget class.

I accessed the necessary field from my primary StatefulWidget class in my build method using widget property.

class ToogleRemarkWidget extends StatefulWidget {
  final TextEditingController textController;
  final String label;
  const ToogleRemarkWidget({
    required this.textController,
    required this.label,
    Key? key,
  }) : super(key: key);

  @override
  State<ToogleRemarkWidget> createState() => _ToogleRemarkWidgetState();
}

class _ToogleRemarkWidgetState extends State<ToogleRemarkWidget> {
  //final TextEditingController _textController = TextEditingController();
  int _toggleIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      mainAxisSize: MainAxisSize.max,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Expanded(
          flex: kIsWeb ? 2 : 5,
          child: Text(widget.label),
        ),
        Expanded(
          flex: kIsWeb ? 2 : 5,
          child: Center(
            child: ToggleSwitch(
              totalSwitches: 2,
              initialLabelIndex: _toggleIndex,
              labels: const ['Okay', 'Not Okay'],
              //TODO Change Okay Icon
              activeBgColors: const [
                [Colors.green],
                [Colors.red]
              ],
              minWidth: 100.0,
              animate: true,
              onToggle: (index) {
                if (index == 0) {
                  widget.textController.clear();
                }
                setState(() {
                  _toggleIndex = index;
                });
              },
              cornerRadius: 20.0,
            ),
          ),
        ),
        Expanded(
          flex: 5,
          child: TextFormField(
            enabled: _toggleIndex == 0 ? false : true,
            controller: widget.textController,
            decoration: InputDecoration(
              icon: const Icon(Icons.note_add),
              label: Text(widget.label),
              hintText: 'Enter ${widget.label}',
              border: const OutlineInputBorder(),
            ),
            validator: (value) {
              if (_toggleIndex == 1 && (value == null || value.isEmpty)) {
                return 'Please enter ${widget.label} By'; //Validation error
              }
              return null; //Validation Success
            },
          ),
        ),
      ],
    );
  }
}
  •  Tags:  
  • Related