Forms 1: User Input

Adding functionality to your AddDogForm is a pretty easy feat.

Essentially, you just need to add a couple built in Flutter classes that keep track of form input, and a function that returns the data to the main page through the router.

1. TextEditingController class

There are a couple ways to go about tracking text input form elements. You can use Form widgets, or you can track each text input separately.

In this example, I will show you how to do the latter. TextEditingController is an important and fundamental thing in Flutter.

A TextEditingController is basically a class that listens to its assigned TextField, and updates it's own internal state every time the text in the TextField changes.

In your _AddDogFormPageState class, add a controller and onChanged property to each TextField:

  1. // new_dog_form.dart
  2. class _AddDogFormPageState extends State<AddDogFormPage> {
  3. // One TextEditingController for each form input:
  4. TextEditingController nameController = TextEditingController();
  5. TextEditingController locationController = TextEditingController();
  6. TextEditingController descriptionController = TextEditingController();
  7. @override
  8. Widget build(BuildContext context) {
  9. return Scaffold(
  10. appBar: AppBar(
  11. title: Text('Add a new Dog'),
  12. backgroundColor: Colors.black87,
  13. ),
  14. body: Container(
  15. color: Colors.black54,
  16. child: Padding(
  17. padding: const EdgeInsets.symmetric(
  18. vertical: 8.0,
  19. horizontal: 32.0,
  20. ),
  21. child: Column(
  22. children: [
  23. Padding(
  24. padding: const EdgeInsets.only(bottom: 8.0),
  25. child: TextField(
  26. // Tell your textfield which controller it owns
  27. controller: nameController,
  28. // Every single time the text changes in a
  29. // TextField, this onChanged callback is called
  30. // and it passes in the value.
  31. //
  32. // Set the text of your controller to
  33. // to the next value.
  34. onChanged: (v) => nameController.text = v,
  35. decoration: InputDecoration(
  36. labelText: 'Name the Pup',
  37. )),
  38. ),
  39. Padding(
  40. padding: const EdgeInsets.only(bottom: 8.0),
  41. child: TextField(
  42. controller: locationController,
  43. onChanged: (v) => locationController.text = v,
  44. decoration: InputDecoration(
  45. labelText: "Pups location",
  46. )),
  47. ),
  48. Padding(
  49. padding: const EdgeInsets.only(bottom: 8.0),
  50. child: TextField(
  51. controller: descriptionController,
  52. onChanged: (v) => descriptionController.text = v,
  53. decoration: InputDecoration(
  54. labelText: 'All about the pup',
  55. )),
  56. ),
  57. Padding(
  58. padding: const EdgeInsets.all(16.0),
  59. child: Builder(
  60. builder: (context) {
  61. return RaisedButton(
  62. onPressed: () => print('PRESSED'),
  63. color: Colors.indigoAccent,
  64. child: Text('Submit Pup'),
  65. );
  66. },
  67. ),
  68. ),
  69. ],
  70. ),
  71. ),
  72. ),
  73. );
  74. }
  75. }

Now, even though it doesn't look like anything new is happening, the TextEditingControllers are keeping track of your form.

2. Submit The Form

Import dog_model.dart into new_dog_form.dart:

  1. // new_dog_form.dart
  2. import 'package:flutter/material.dart';
  3. import 'dog_model.dart';

In the same _AddDogFormPageState class, add the submitPup function, which will pass the form information back via the Navigator:

  1. // new_dog_form.dart
  2. // You'll need the context in order for the Navigator to work.
  3. void submitPup(BuildContext context) {
  4. // First make sure there is some information in the form.
  5. // A dog needs a name, but may be location independent,
  6. // so we'll only abandon the save if there's no name.
  7. if (nameController.text.isEmpty) {
  8. print('Dogs need names!');
  9. } else {
  10. // Create a new dog with the information from the form.
  11. var newDog = Dog(nameController.text, locationController.text,
  12. descriptionController.text);
  13. // Pop the page off the route stack and pass the new
  14. // dog back to wherever this page was created.
  15. Navigator.of(context).pop(newDog);
  16. }
  17. }

And lastly, add submitPup to your 'RaisedButton' onPressed callback:

  1. // new_dog_form.dart
  2. builder: (BuildContext context) {
  3. return RaisedButton(
  4. onPressed: () => submitPup(context),
  5. color: Colors.indigoAccent,
  6. child: Text('Submit Pup'),
  7. );
  8. },

And that's that. Now, you should be able to submit a new dog and see it on your main page!