Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load form values from object or map ? #101

Closed
LucaGabi opened this issue Jul 26, 2019 · 11 comments
Closed

Load form values from object or map ? #101

LucaGabi opened this issue Jul 26, 2019 · 11 comments
Labels
duplicate This issue or pull request already exists enhancement New feature or request question Further information is requested

Comments

@LucaGabi
Copy link

LucaGabi commented Jul 26, 2019

Hi, how can I load form data from an object after rest api call ?
I tried initalValue..

@danvick
Copy link
Collaborator

danvick commented Jul 26, 2019

Loading initialValue for the whole form from map is not currently available in the current version.

It will, however, be available as from version 3.3.0 which is in the works and will be released soon. Thanks for your patience, and contributions. Keep 'em coming.

@danvick danvick added enhancement New feature or request duplicate This issue or pull request already exists labels Jul 26, 2019
@LucaGabi
Copy link
Author

The problem is I can't populate the form values after an api call .. even one by one .. how to do that ? The form dose not re-render.. I tried FutureBuilder .. Is there a solution?

Thanks!

@danvick
Copy link
Collaborator

danvick commented Jul 26, 2019

I'm confident thatFutureBuilder should work because I'm using it in production.
Kindly share an excerpt of your code for assistance.

@danvick danvick added the question Further information is requested label Jul 26, 2019
@LucaGabi
Copy link
Author

children: <Widget>[
                 FutureBuilder(
                   future: _model.loadClient(_routeArgs),
                   builder: (context, AsyncSnapshot<ClientResponse> snapshot) =>
                      FormBuilder(
                    key: _fbKeyClient,
                    // autovalidate: true,
                    child: Column(
                      children: <Widget>[
                        FormBuilderTextField(
                          readonly: !_model.isNewClient,
                          initialValue: _model?.client?.data?.name,
                          attribute: "name",
                          decoration: InputDecoration(labelText: "Nume"),
                          validators: [
                            FormBuilderValidators.required(
                                errorText: "*informatie obligatorie"),
                            FormBuilderValidators.pattern("[a-zA-Z ]{3,}",
                                errorText: "*nume in format invalid")
                          ],
                        ),
                        FormBuilderTextField(
                          readonly: !_model.isNewClient,
                          initialValue: _model?.client?.data?.email,
                          attribute: "email",
                          decoration:
                              InputDecoration(labelText: "Adresa de email"),
                          validators: [
                            FormBuilderValidators.required(
                                errorText: "*informatie obligatorie"),
                            FormBuilderValidators.email(
                                errorText: "*email in format invalid")
                          ],
                        ),
                        FormBuilderTextField(
                          readonly: !_model.isNewClient,
                          initialValue: _model?.client?.data?.pin,
                          attribute: "pin",
                          keyboardType: TextInputType.number,
                          decoration: InputDecoration(labelText: "PIN"),
                          obscureText: true,
                          validators: [
                            FormBuilderValidators.required(
                                errorText: "*informatie obligatorie"),
                            FormBuilderValidators.pattern("[0-9]{4,}",
                                errorText: "*pin in format invalid")
                          ],
                        ),
                        FormBuilderTextField(
                          readonly: !_model.isNewClient,
                          initialValue: _model?.client?.data?.phone,
                          attribute: "phone",
                          decoration: InputDecoration(labelText: "Telefon"),
                          validators: [
                            FormBuilderValidators.required(
                                errorText: "*informatie obligatorie"),
                            FormBuilderValidators.pattern("^07[0-9]{8,8}\$",
                                errorText: "*telefon in format invalid")
                          ],
                        ),
                        FormBuilderTextField(
                          readonly: !_model.isNewClient,
                          initialValue: _model?.client?.data?.cnp,
                          attribute: "cnp",
                          // keyboardType: TextInputType.number,
                          decoration: InputDecoration(labelText: "CNP"),
                          validators: [
                            FormBuilderValidators.required(
                                errorText: "*informatie obligatorie"),
                            (valueCandidate) {
                              if (valueCandidate != null &&
                                  valueCandidate.isNotEmpty) {
                                if (!H.validCNP(valueCandidate))
                                  return "*cnp invalid";
                              }
                              return null;
                            }
                          ],
                        ),
                        FormBuilderDateTimePicker(
                          readonly: !_model.isNewClient,
                          attribute: "birthDate",
                          initialValue: _model?.client?.data?.birthDate != null
                              ? _model?.client?.data?.birthDate
                              : null,
                          inputType: InputType.date,
                          format: DateFormat("dd-MM-yyyy"),
                          decoration:
                              InputDecoration(labelText: "Data nasterii"),
                          validators: [
                            (valueCandidate) {
                              if (valueCandidate == null) {
                                return "*camp obligatoriu";
                              }
                              return null;
                            }
                          ],
                        ),
                        FormBuilderCheckboxList(
                            initialValue: [],
                            decoration: InputDecoration(
                                labelStyle: TextStyle(fontSize: 22),
                                labelText: "Membrii"),
                            attribute: "members",
                            onChanged: (v) =>
                                _model.setSessionMembers(v as List<dynamic>),
                            options: _model.client?.data?.children
                                    ?.map(
                                      (f) => FormBuilderFieldOption(
                                        value: f.id,
                                        label: f.name,
                                      ),
                                    )
                                    ?.toList() ??
                                []
                            // options: [
                            // FormBuilderFieldOption(value: "Dart"),
                            // ...
                            // ],
                            ),
                        FormBuilderSwitch(
                          readonly: !_model.isNewClient,
                          label: new Text(
                            "Vreau sa primesc noutati pe email",
                            style: new TextStyle(fontSize: 16),
                          ),
                          attribute: "emailNewsAccept",
                          initialValue: true,
                        ),
                        FormBuilderSwitch(
                          readonly: !_model.isNewClient,
                          label: new Text(
                            "Vreau sa primesc noutati pe SMS",
                            style: new TextStyle(fontSize: 16),
                          ),
                          attribute: "smsNewsAccept",
                          initialValue: true,
                        ),
                        FormBuilderSwitch(
                          readonly: !_model.isNewClient,
                          onChanged: (v) {
                            UIHelper.openWebview(
                                context: context,
                                title: "Termenii si conditii");
                          },
                          validators: [
                            FormBuilderValidators.requiredTrue(
                                errorText: "*obligatoriu"),
                          ],
                          label: new Text(
                            "Accept termenii si conditii",
                            style: new TextStyle(
                                color: Colors.purple,
                                decoration: TextDecoration.underline,
                                fontSize: 16),
                          ),
                          attribute: "termsAccept",
                          initialValue: false,
                        ),
                        FormBuilderSwitch(
                          readonly: !_model.isNewClient,
                          validators: [
                            FormBuilderValidators.requiredTrue(
                                errorText: "*obligatoriu"),
                          ],
                          label: new Text(
                            "Accept GDPR",
                            style: new TextStyle(fontSize: 16),
                          ),
                          attribute: "gdprAccept",
                          initialValue: false,
                        ),
                      ],
                    ),
                  ),
                ),
                Row(
                  children: <Widget>[
                    Expanded(
                      child: Padding(
                        padding: const EdgeInsets.all(16.0),
                        child: RaisedButton(
                          elevation: 6.0,
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(30.0)),
                          color: Theme.of(context).primaryColor,
                          child: Text("Pasul urmator",
                              style: TextStyle(color: Colors.white)),
                          onPressed: () => _onGDPRFormNextClick(context),
                        ),
                      ),
                    ),
                    Expanded(
                      child: Padding(
                        padding: const EdgeInsets.all(16.0),
                        child: RaisedButton(
                          elevation: 6.0,
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(30.0)),
                          // color: Colors.green,
                          child: Text("Renunta",
                              style: TextStyle(color: Colors.white)),
                          onPressed: cancelClientSession,
                        ),
                      ),
                    ),
                  ],
                )
              ]

@LucaGabi
Copy link
Author

It only works the first time with the initialValue ..

@LucaGabi
Copy link
Author

I have another form and I call _fbKeyAddMember.currentState.reset(); should this not clear the form ?

@LucaGabi
Copy link
Author

From the example .. reset dose not work for dates and others ..

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';

import './data.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter FormBuilder Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  MyHomePageState createState() {
    return MyHomePageState();
  }
}

class MyHomePageState extends State<MyHomePage> {
  var data;
  bool autoValidate = true;
  bool readOnly = false;
  bool showSegmentedControl = true;
  final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
  final GlobalKey<FormFieldState> _specifyTextFieldKey =
      GlobalKey<FormFieldState>();

  ValueChanged _onChanged = (val) => print(val);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FormBuilder Example"),
      ),
      body: Padding(
        padding: EdgeInsets.all(10),
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              FormBuilder(
                // context,
                key: _fbKey,
                autovalidate: true,
                // readonly: true,
                child: Column(
                  children: <Widget>[
                    FormBuilderCustomField(
                      attribute: "name",
                      validators: [
                        FormBuilderValidators.required(),
                      ],
                      formField: FormField(
                        // key: _fieldKey,
                        enabled: true,
                        builder: (FormFieldState<dynamic> field) {
                          return InputDecorator(
                            decoration: InputDecoration(
                              labelText: "Select option",
                              contentPadding:
                                  EdgeInsets.only(top: 10.0, bottom: 0.0),
                              border: InputBorder.none,
                              errorText: field.errorText,
                            ),
                            child: DropdownButton(
                              isExpanded: true,
                              items: ["One", "Two"].map((option) {
                                return DropdownMenuItem(
                                  child: Text("$option"),
                                  value: option,
                                );
                              }).toList(),
                              value: field.value,
                              onChanged: (value) {
                                field.didChange(value);
                              },
                            ),
                          );
                        },
                      ),
                    ),
                    FormBuilderChipsInput(
                      decoration: InputDecoration(labelText: "Chips"),
                      attribute: 'chips_test',
                      // readonly: true,
                      onChanged: _onChanged,
                      // valueTransformer: (val) => val.length > 0 ? val[0] : null,
                      initialValue: [
                        Contact('Andrew', 'stock@man.com',
                            'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
                      ],
                      maxChips: 5,
                      findSuggestions: (String query) {
                        if (query.length != 0) {
                          var lowercaseQuery = query.toLowerCase();
                          return mockResults.where((profile) => 
                                profile.name
                                    .toLowerCase()
                                    .contains(query.toLowerCase()) ||
                                profile.email
                                    .toLowerCase()
                                    .contains(query.toLowerCase())
                          ).toList(growable: false)
                            ..sort((a, b) => a.name
                                .toLowerCase()
                                .indexOf(lowercaseQuery)
                                .compareTo(b.name
                                    .toLowerCase()
                                    .indexOf(lowercaseQuery)));
                        } else {
                          return const <Contact>[];
                        }
                      },
                      chipBuilder: (context, state, profile) {
                        return InputChip(
                          key: ObjectKey(profile),
                          label: Text(profile.name),
                          avatar: CircleAvatar(
                            backgroundImage: NetworkImage(profile.imageUrl),
                          ),
                          onDeleted: () => state.deleteChip(profile),
                          materialTapTargetSize:
                              MaterialTapTargetSize.shrinkWrap,
                        );
                      },
                      suggestionBuilder: (context, state, profile) {
                        return ListTile(
                          key: ObjectKey(profile),
                          leading: CircleAvatar(
                            backgroundImage: NetworkImage(profile.imageUrl),
                          ),
                          title: Text(profile.name),
                          subtitle: Text(profile.email),
                          onTap: () => state.selectSuggestion(profile),
                        );
                      },
                    ),
                    FormBuilderDateTimePicker(
                      attribute: "date",
                      onChanged: _onChanged,
                      // inputType: InputType.date,
                      format: DateFormat("yyyy-MM-dd"),
                      decoration:
                          InputDecoration(labelText: "Appointment Time"),
                      // readonly: true,
                    ),
                    FormBuilderSlider(
                      attribute: "slider",
                      validators: [FormBuilderValidators.min(6)],
                      onChanged: _onChanged,
                      min: 0.0,
                      max: 10.0,
                      initialValue: 7.0,
                      divisions: 20,
                      activeColor: Colors.red,
                      inactiveColor: Colors.pink[100],
                      decoration: InputDecoration(
                        labelText: "Number of somethings",
                      ),
                    ),
                    FormBuilderCheckbox(
                      attribute: 'accept_terms',
                      initialValue: false,
                      onChanged: _onChanged,
                      leadingInput: true,
                      label: Text(
                          "I have read and agree to the terms and conditions"),
                      validators: [
                        FormBuilderValidators.requiredTrue(
                          errorText:
                              "You must accept terms and conditions to continue",
                        ),
                      ],
                    ),
                    FormBuilderDropdown(
                      attribute: "gender",
                      decoration: InputDecoration(labelText: "Gender"),
                      initialValue: 'Male',
                      readonly: true,
                      hint: Text('Select Gender'),
                      validators: [FormBuilderValidators.required()],
                      items: ['Male', 'Female', 'Other']
                          .map((gender) => DropdownMenuItem(
                                value: gender,
                                child: Text('$gender'),
                              ))
                          .toList(),
                    ),
                    FormBuilderTextField(
                      attribute: "age",
                      decoration: InputDecoration(labelText: "Age"),
                      onChanged: _onChanged,
                      valueTransformer: (text) => num.tryParse(text),
                      validators: [
                        FormBuilderValidators.numeric(),
                        FormBuilderValidators.max(70),
                      ],
                    ),
                    FormBuilderTypeAhead(
                      // initialValue: "Canada",
                      decoration: InputDecoration(labelText: "Country"),
                      attribute: 'country',
                      onChanged: _onChanged,
                      itemBuilder: (context, country) {
                        return ListTile(
                          title: Text(country),
                        );
                      },
                      suggestionsCallback: (query) {
                        if (query.length != 0) {
                          var lowercaseQuery = query.toLowerCase();
                          return allCountries.where((country) {
                            return country
                                .toLowerCase()
                                .contains(lowercaseQuery);
                          }).toList(growable: false)
                            ..sort((a, b) => a
                                .toLowerCase()
                                .indexOf(lowercaseQuery)
                                .compareTo(
                                    b.toLowerCase().indexOf(lowercaseQuery)));
                        } else {
                          return allCountries;
                        }
                      },
                    ),
                    FormBuilderRadio(
                      decoration:
                          InputDecoration(labelText: 'My chosen language'),
                      attribute: "best_language",
                      leadingInput: true,
                      onChanged: _onChanged,
                      validators: [FormBuilderValidators.required()],
                      options: [
                        "Dart",
                        "Kotlin",
                        "Java",
                        "Swift",
                        "Objective-C"
                      ]
                          .map((lang) => FormBuilderFieldOption(value: lang))
                          .toList(growable: false),
                    ),
                    FormBuilderSegmentedControl(
                      decoration:
                          InputDecoration(labelText: "Movie Rating (Archer)"),
                      attribute: "movie_rating",
                      options: List.generate(5, (i) => i + 1)
                          .map(
                              (number) => FormBuilderFieldOption(value: number))
                          .toList(),
                      onChanged: _onChanged,
                    ),
                    FormBuilderSwitch(
                      label: Text('I Accept the tems and conditions'),
                      attribute: "accept_terms_switch",
                      initialValue: true,
                      onChanged: _onChanged,
                    ),
                    FormBuilderStepper(
                      decoration: InputDecoration(labelText: "Stepper"),
                      attribute: "stepper",
                      initialValue: 10,
                      step: 1,
                      onChanged: (data) {
                        //_fbKey.currentState.fields['age'].currentState.didChange("$data");
                        //_fbKey.currentState.setAttributeValue("age", "$data");
                      },
                      validators: [
                        (val) {
                          if (!_fbKey.currentState.fields["accept_terms_switch"]
                                  .currentState.value &&
                              val >= 10) {
                            return "You can only put more than 10 if you've accepted terms";
                          }
                          return null;
                        }
                      ],
                    ),
                    FormBuilderRate(
                      decoration: InputDecoration(labelText: "Rate this form"),
                      attribute: "rate",
                      iconSize: 32.0,
                      initialValue: 1,
                      max: 5,
                      onChanged: _onChanged,
                    ),
                    FormBuilderCheckboxList(
                      decoration: InputDecoration(
                          labelText: "The language of my people"),
                      attribute: "languages",
                      initialValue: ["Dart"],
                      leadingInput: true,
                      options: [
                        FormBuilderFieldOption(value: "Dart"),
                        FormBuilderFieldOption(value: "Kotlin"),
                        FormBuilderFieldOption(value: "Java"),
                        FormBuilderFieldOption(value: "Swift"),
                        FormBuilderFieldOption(value: "Objective-C"),
                      ],
                      onChanged: _onChanged,
                    ),
                    FormBuilderCustomField(
                      attribute: 'custom',
                      valueTransformer: (val) {
                        if (val == "Other")
                          return _specifyTextFieldKey.currentState.value;
                        return val;
                      },
                      formField: FormField(
                        builder: (FormFieldState<String> field) {
                          var languages = [
                            "English",
                            "Spanish",
                            "Somali",
                            "Other"
                          ];
                          return InputDecorator(
                            decoration: InputDecoration(
                                labelText: "What's your preferred language?"),
                            child: Column(
                              children: languages
                                  .map(
                                    (lang) => Row(
                                      children: <Widget>[
                                        Radio<dynamic>(
                                          value: lang,
                                          groupValue: field.value,
                                          onChanged: (dynamic value) {
                                            field.didChange(lang);
                                          },
                                        ),
                                        lang != "Other"
                                            ? Text(lang)
                                            : Expanded(
                                                child: Row(
                                                  children: <Widget>[
                                                    Text(
                                                      lang,
                                                    ),
                                                    SizedBox(width: 20),
                                                    Expanded(
                                                      child: TextFormField(
                                                        key:
                                                            _specifyTextFieldKey,
                                                      ),
                                                    ),
                                                  ],
                                                ),
                                              ),
                                      ],
                                    ),
                                  )
                                  .toList(growable: false),
                            ),
                          );
                        },
                      ),
                    ),
                    FormBuilderSignaturePad(
                      decoration: InputDecoration(labelText: "Signature"),
                      attribute: "signature",
                      // height: 250,
                      clearButtonText: "Start Over",
                      onChanged: _onChanged,
                    ),
                  ],
                ),
              ),
              Row(
                children: <Widget>[
                  Expanded(
                    child: MaterialButton(
                      color: Theme.of(context).accentColor,
                      child: Text(
                        "Submit",
                        style: TextStyle(color: Colors.white),
                      ),
                      onPressed: () {
                        _fbKey.currentState.save();
                        if (_fbKey.currentState.validate()) {
                          print(_fbKey.currentState.value);
                        } else {
                          print(_fbKey.currentState.value);
                          print("validation failed");
                        }
                      },
                    ),
                  ),
                  SizedBox(
                    width: 20,
                  ),
                  Expanded(
                    child: MaterialButton(
                      color: Theme.of(context).accentColor,
                      child: Text(
                        "Reset",
                        style: TextStyle(color: Colors.white),
                      ),
                      onPressed: () {
                        _fbKey.currentState.reset();
                      },
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

@danvick
Copy link
Collaborator

danvick commented Jul 29, 2019

I'm unable to reproduce the refresh error.

Does the _model.loadClient(_routeArgs) function include setState?

@danvick
Copy link
Collaborator

danvick commented Jul 29, 2019

Kindly open different issues for different challenges you are facing as it will help the community assist easily.
I see upto 3 different issues in this issue which could be handled separately.

@LucaGabi
Copy link
Author

LucaGabi commented Aug 1, 2019

Ok, I will. Yes includes setState ..

With the example you provided it still dose not work certain fields don't get cleared.

@danvick
Copy link
Collaborator

danvick commented Aug 21, 2019

Hi all,
This feature was added in version 3.3.0 of the package - published on 28-Jul-2019.

Kindly try it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants