Search code examples
flutterdartkeyglobal

Flutter List of GlobalKeys


I have a dynamic list that is formed by the items that I select on another screen, in each item I generate a label with the name of the item and next to a TextField to add more information to that item

Controllers:

 controller: TextEditingController.fromValue(
  TextEditingValue(
   selection: new TextSelection.collapsed(
     offset: items[index].length),
    ),
  ),

Label:

Text(items[index].trim())

inside the textfield which can be 1 textfield or 1000 textfields I need to take the value that was written in it and save it in a list when I click the save button. And for that I created a form with a globalkey so after doing the validation it saves, but I only have 1 globakey and I can have several items

final _formKey = GlobalKey<FormState>();

This is my form:

    Form(
    key: _formKey,
    child: Expanded(
      child: TextFormField(
         validator: (value) {
            if (int.parse(value) > 999999) {
              return 'error';
             }
            },
          decoration: InputDecoration(
          labelText: unitOfMeasurement,
            labelStyle: TextStyle(
            fontSize: 10,
            fontFamily: 'Montserrat',
            fontWeight: FontWeight.bold,
            color: Colors.grey),
           ),
           keyboardType: TextInputType.number,
           inputFormatters: [
             TextInputMask(
               mask: '\ !9+.99',
               placeholder: '0',
               maxPlaceHolders: 3,
               reverse: true)
             ],
           controller: TextEditingController.fromValue(
           TextEditingValue(
           selection: new TextSelection.collapsed(
           offset: items[index].length),
           ),
         ),
         onSaved: (String val){
         weigthItems.add(val.trim());
         print(val);
       },
      ),
    ),
  ),

    

And my key:

final _formKey = GlobalKey<FormState>();

Save:

if(_formKey.currentState.validate()){
                      _formKey.currentState.save();
                      _receipt.weigthIngredients = weigthItems.toString().trim();
                    }

Solution

  • Only one _formKey is enough for all the form fields make sure Form() is the parent of all the TextFormField

    Example:

    Container(child: Form(
            key: _key,
            child: Column(
              children: [
                TextFormField(),
                TextFormField(),
                TextFormField(),
                TextFormField(),
                ..... // N number of form fields with validation
                TextButton(onPressed: (){
                  if (_form.currentState.validate()){
                    // validates all the field
                  }
                  
                }, child: Text('validate')),
    
              ],
            ),
          )
    

    Edit:

    You are creating multiple forms with same key I have modified your code this should work

    
    showFormDialogWeigth(BuildContext context) async {
      weigthItems.clear();
      items = isChecked.toList();
    
      return showDialog(
        context: context,
        builder: (context) {
          return StatefulBuilder(
            builder: (context, setState) {
              return AlertDialog(
                title: Text(
                  'INFORME O PESO',
                  style: TextStyle(
                      fontSize: 18,
                      fontFamily: 'Montserrat',
                      fontWeight: FontWeight.bold,
                      color: Colors.grey),
                ),
                content: Form(
                  key: _formKey,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Container(
                        height: 250,
                        width: 280,
                        child: ListView.builder(
                          shrinkWrap: true,
                          itemBuilder: (context, index) {
                            return ListTile(
                              title: Row(
                                children: <Widget>[
                                  Expanded(
                                    child: Text(
                                      items[index].trim(),
                                      style: TextStyle(
                                          fontSize: 14,
                                          fontFamily: 'Montserrat',
                                          fontWeight: FontWeight.bold,
                                          color: Colors.grey),
                                    ),
                                  ),
                                  Expanded(
                                    child: TextFormField(
                                      validator: (value) {
                                        if (int.parse(value) > 999999) {
                                          return 'valor incorreto';
                                        }
                                        return null;
                                      },
                                      decoration: InputDecoration(
                                        labelText: unitOfMeasurement,
                                        labelStyle: TextStyle(
                                            fontSize: 10,
                                            fontFamily: 'Montserrat',
                                            fontWeight: FontWeight.bold,
                                            color: Colors.grey),
                                      ),
                                      keyboardType: TextInputType.number,
                                      inputFormatters: [
                                        TextInputMask(
                                            mask: '\ !9+.99',
                                            placeholder: '0',
                                            maxPlaceHolders: 3,
                                            reverse: true)
                                      ],
                                      controller: TextEditingController.fromValue(
                                        TextEditingValue(
                                          selection: new TextSelection.collapsed(
                                              offset: items[index].length),
                                        ),
                                      ),
                                      onSaved: (String val){
                                        weigthItems.add(val.trim());
                                        print(val);
                                      },
                                      // onChanged: (value) async {
                                      //   _debouncer.run(() {
                                      //     weigthItems.add(value.trim());
                                      //     print(weigthItems);
                                      //   });
                                      // },
                                    ),
                                  ),
                                ],
                              ),
                              subtitle: Row(
                                children: <Widget>[
                                  Expanded(
                                    child: Text(
                                      timeOrTurns.toString(),
                                      style: TextStyle(
                                          fontSize: 10,
                                          fontFamily: 'Montserrat',
                                          fontWeight: FontWeight.bold,
                                          color: Colors.grey),
                                    ),
                                  ),
                                  Expanded(
                                    child: TextFormField(
                                      decoration: InputDecoration(
                                        hintText: "Max 600",
                                        hintStyle: TextStyle(
                                            fontSize: 10,
                                            fontFamily: 'Montserrat',
                                            fontWeight: FontWeight.bold,
                                            color: Colors.grey),
                                      ),
                                      keyboardType: TextInputType.number,
                                      controller: TextEditingController.fromValue(
                                        TextEditingValue(
                                          selection: new TextSelection.collapsed(
                                              offset: items[index].length),
                                        ),
                                      ),
                                      onChanged: (value) async {
                                        if (int.parse(value) < 600) {
                                          _debouncer.run(
                                                () {
                                              timeItems.add(value);
                                              print(timeItems);
                                            },
                                          );
                                        }
                                      },
                                    ),
                                  ),
                                ],
                              ),
                            );
                          },
                          itemCount: items.length,
                        ),
                      ),
                      Container(
                        width: 200,
                        height: 30,
                        child: TextField(
                          maxLength: 2,
                          keyboardType: TextInputType.number,
                          controller: totalTime,
                          decoration: InputDecoration(
                              disabledBorder: OutlineInputBorder(
                                borderSide: BorderSide(
                                  color: Colors.grey,
                                ),
                                borderRadius: BorderRadius.circular(10.0),
                              ),
                              hintText: "TEMPO TOTAL DE MISTURA",
                              hintStyle: TextStyle(
                                  fontSize: 10,
                                  fontFamily: 'Montserrat',
                                  fontWeight: FontWeight.bold,
                                  color: Colors.grey)),
                        ),
                      ),
                    ],
                  ),
                ),
                actions: <Widget>[
                  FlatButton(
                    onPressed: () async {
                      Navigator.pop(context);
                    },
                    child: Text(
                      'VOLTAR',
                      style: TextStyle(color: Colors.green),
                    ),
                  ),
                  FlatButton(
                    onPressed: () async {
    
                      if(_formKey.currentState.validate()){
                        _formKey.currentState.save();
                        _receipt.weigthIngredients = weigthItems.toString().trim();
                      }
    
                      _receipt.unitOfMeasurement = unitOfMeasurement.toString();
                      _receipt.timeOrTurns = timeOrTurns.toString();
                      _receipt.valueMix = timeItems.toString();
                      _receipt.totalMix = totalTime.text;
    
                      var result = await _receiptService.saveReceipt(_receipt);
                      if (result > 0) {
                        getAllReceipt();
                        print(timeItems);
                        print(weigthItems);
                        print(totalTime);
                        Navigator.pushNamed(context, AppRoutes.RECEIPTS);
                      }
                    },
                    child: Text(
                      'SALVAR',
                      style: TextStyle(color: Colors.green),
                    ),
                  ),
                ],
              );
            },
          );
        },
      );
    }