Instructor: To start using Material inputs, you need to include the matInput module in your NgModule imports. Every input in textarea requires the matInput directive. This allows it to be identified within a Material form field container, which we'll see here in a second. At this point, our input is still vanilla. We have no additional Material Design styling here, as you can see.
To include Material Design styling and functionality, we need to wrap the input in the mat-form-field component. This holds true for the majority of form controls, including Material Design selects and datepickers. When we refresh, we now have the Material Design focused underline we're used to.
Next, we'll add a placeholder. Let's call it "basic input." Let's see how this looks. By default, you get a placeholder that floats on focus. If you want to change this functionality, then you can change the floatPlaceholder input on the mat-form-field component.
The three options are auto, which we just saw. The second options is always, which we'll see here. This keeps the placeholder floating above the input, whether there's focus or not. The remaining placeholder option is never, which behaves like a classic input placeholder and disappears once you start typing.
Suppose you like this functionality, but you don't want to have to override it in every form field. To fix this, you can utilize the mat-placeholder global options token and include this in your NgModule providers, overriding the value.
For this case, we're going to set the value of float to never, matching the settings we had in our last example. When we refresh, we'll see the exact same functionality even though we didn't utilize the floatPlaceholder input in our template.
Now, wrapping our inputs in the mat-form-field component enables some pretty cool features for our inputs. The first we're going to look at are text hints. A good use case for hints are form fields that have special requirements or restrictions.
In this example, we have a password field. We need to tell the users that there's one special character required for all passwords. To do this, we can use the mat-hint component. By default, all hints appear at the bottom of the form field that started the input, but we can adjust this by using the align property.
The two options are start, which is the default, but if you want the hint to appear at the end of the input, you can use the align="end" setting. You can also combine starting and ending hints. In this case, we moved our special character hint to the start while we added a length hint to the end. When the user types, our end hint now displays how many valid characters they have remaining.
Material form fields also makes handling the display of input errors quite easy. For this example, we added an ngModel binding to our input. We also added a minlength requirement of six characters and a required attribute to our field for demonstration purposes.
By default, the required attribute adds an asterisk to our placeholder, signifying that this field is needed. At this point, if we come over and type into our input, and then remove the text, and lose focus, we'll see that the field turns red, signifying that this is an invalid state.
Let's see how we can present the user with more information regarding each one of these possible error states. The first thing we need to do is create a reference to our ngModel so we can pick up the errors on our password input.
We can now utilize the mat-errors component for error display. We'll control this display through a combination of ngIf and the errors object on our password input. When the required error is found, we want to show a message to our user. For now, we'll just say, "This field is required."
Let's see how this looks when we refresh. When we type into our input, and we lose focus, we can now see the error message that we supplied is shown. When we type back into the input, our hint reappears.
Next, let's add the minlength error so we can see how multiple errors are handled. Now, when we type, and the field loses focus, you'll see that our "Six characters required" error appears. If we meet this requirement, it disappears. If we go back, then our "Field is required" error will reappear.
One thing you may have noticed up to this point is no errors are shown until the field is touched and then loses focus at least once, but what if we want to show errors right away? We can do this by implementing a custom error matcher strategy.
All we have to do is create a class that implements the ErrorStateMatcher interface. This interface contains one method, isErrorState, which accepts a control and a form, returning a Boolean determining whether we should show error messages yet or not.
In this case, we're going to override the default behavior, and go ahead and show error messages as soon as the control is both 30 and invalid. Next, we'll add this custom error matcher into our component providers and inject it into our component.
All that's left to do is add the ErrorStateMatcher input to our Material input, passing it our custom ErrorStateMatcher. Now, when we type into the form field, we'll see errors appear immediately rather than waiting for focus to be lost.