Flutter UI Widgets

Nov 9 2021 · Dart 2.14, Flutter 2.5, VS Code 1.61

Part 1: Flutter UI Widgets

10. Work with Forms

Episode complete

Play next episode

About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 09. Add Navigation & SliverAppBar Next episode: 11. Display Dialogs

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

Forms are very essential in almost every app and Flutter gives us various ways to handle user inputs. We can manually handle inputs using various techniques, but in this episode, we'll be using the form widget, which is more robust. I've linked the floating action button to navigate to the create_article page. This is included in the startup project of this episode. Before we start coding the form, we need a way to hold the data that is being entered in the form. And for this, I've provided the FormData model, which is stored inside the models folder. Go ahead and open it up. It has all the values we intend collecting from the form. Normally we should have used the article model, but it contains all the strings and that's kind of limiting for this example, since we'll be covering other inputs widgets. And that's why the custom FormData model was created. Let's go ahead and make use of it. Head back to the create_article page and enter the following code. This creates a FormData object that will hold our form field values. Next, let's create a basic form. Place in the following code. Save your work. And you can see the corresponding UI. Now let's break down the code. First, we turn the form which contains a text form field and an elevated button. The form is simply a container for this form fields, just like the one we added. You'll see the benefits of using the form shortly. A text form field as a form field that contains a text field. With this widget, you get a text edits in controller automatically. If you use the basic text field, you'd have to manually connect the text editing controller to retrieve its value. We set its liberal texts in the impute decoration class. This class is used to style imputes with borders, icons, hints, text, and other stallion attributes. Also, we added a basic validator. The validated back function checks to see the text is empty, and if it is empty, the validation fails and returns an error message. If there are no errors, the validator must return no. Next, the unsaved method is called when we submit the form. Yeah, we set the FormData's title to the impute value. Now you might ask, how do we submit this form? Well, that leads us to the next stage, the form needs a key. Keys are used in Flutter to uniquely identify widgets and they contain some additional information. We'll be using the global key to study state of the form. Global keys are unique across the entire app. Okay, let's add that now. In here, we created a global key of Typeform state. A from state Objects can be used to save, reset and validate every form field that is inside the correspondent form. Next, we assign the form key to the key property of the form widget. Now that we are done with that, let's add the code to save the form where we hit the save button, and the following course with the unpressed method of the button. Save your work, after the updates. we get the current state of the form from the form key variable. Then we check to see if the form is valid. The validate method executes the validator of each form field. It returns true if every form field is valid. The form will then rebuild to report it's results. And this is possible because, the form is a state of widgets. If the form is valid, then we call the save method and this calls the unsaved method for all the form fields that is associated with the form. In this case, we only have one form field. So it will call the unsaved method for just that form field. And the unsaved method, save the value of the text fields of the FormData objects. And we can see that from the text form field we created earlier. Next, we print the FormData to the debug console, and finally, we clear the form by calling the reset method. As you can see, all this bulk operations are possible, simply because we're using the form widgets, which has all the necessary functionalities to process imputes effectively. And the last line programmatically hides the keyboard, when you press the submit button. Okay, enough talk, let's try it out now. First let's submit the form with an empty title field. You can see the validator kicks in and declares the form invalid. And it also shows the correspondent error message. Now let's go ahead and add some texts. And we submit the form. You can see the text field is cleared. And let's check the console to see if it prints out the value. Open up the debug console by pressing control shift Y on windows or command shift Y for Mac users. And you can see, it prints out an instance of the FormData class. Now we got the form set up with the title field, let's implement other fields. I'll go ahead and update this file, I'll explain the new additions. I've added other form fields here. Some of them are very similar to the title text. I also added some custom validation, although in a production app, you'd write better validation, or simply use a library. Let's go over the easy ones first. This is the image URL text form field. And it's validator simply checks to see if the text entered is an actual URL. The content validator checks if the field is empty or has a length less than 10. The email validator simply because a function that validates the email. Let's scroll up to that function. In this method, I declared a string pattern that conforms to the format of an email address. Next, we pass the string to regular expression. We then check to see if the value entered matches the regular expression pattern. If it doesn't, we return an error message. And if it does, we return null to signify the value was valid. And by the way, I spent about two years memorizing the string pattern. It's very difficult, but it's actually doable. Okay seriously, you can find regular expression patterns all over the internet. Next we have the switch list tile widgets. It is a switch widget with some additional styling to make it look like a ListTile. this widget does not manage your state like the text phone field. So we manually call the set states to update the FormData, which is values whenever the user topples the switch. And we do this in the onChanged callback function. Next is a RadioListTile widget. And these are radio buttons, where the user select only one value from the group. Just like the switch list tile, it does not manage the states, so we use set states when the radio button is selected. And one property to take note is the groupValue. You simply assign both buttons, the same groupValue variable, and this links the two radio buttons together, so that you can only select one of them. Now that you are done with all the explanations, we need to fill the form and try it out. But before that, we need to restate the state of both the switch and the radio button to the initial values, since they are not linked to the form states. Enter the following code in the on press method. And save your work. Let's fill out the form. Then you click on the save button. And you have the form values saved successfully, and the form resets. Open up the debug console to see the values, and you can see the FormData instance prints successfully. And you could assess a member by printing out FormData.title, or something. But I'll leave that up to you.