2.5 Build a Form Class
Creating custom routes in your application is fun and useful, but how often would you just want to give your customer a URL scheme and have them manually input data into it? The answer is never. A more common scenario is to create a form that will send data to the server and allow you to redirect the browser to your route. In this lesson, you will learn the basics of building a custom form using the Drupal 8 Form API.
1.Introduction2 lessons, 05:24
2.Drupal Module Basics6 lessons, 48:45
3.Create the Calculator Module4 lessons, 28:15
4.Conclusion1 lesson, 02:31
2.5 Build a Form Class
Now that we kind of understand the basics of routes and controllers and parameters, let's introduce a new concept into the fray here so that we can really start to add some really cool interactions with the end user and have our application or our module handle those types of things in the background for us. So now what I wanna do is I want to start creating a form that we will present to the user and get some input and then have them send that to us. Now previously when we created our other route in our controller we started from the other route perspective. But now this time let's go ahead and start with the class perspective and we'll start to dig into that a little bit and see what it looks like to create a form within your module. So in order do this and keep things fairly organized nicely, let's go back into our source folder, let's create a new folder and we're gonna call this Form. Now within here I'm going to create a new file. So let's go ahead and say New File and we're gonna call this CalculatorForm.php. Now I know the naming conventions don't really make a lot sense with our logic so far. It's just because I'm creating them this way and we're gonna modify them a little bit later on to actually become the calculator that we want to end up using. But in this case, now I have a calculator Form.php file. So once again, this is going to be a PHP file so let's go ahead and create our open and close PHP tags. And now we want to start handling this form, a very similarly to how we handled our controller. The first thing we wanna do, is wanted to find namespace. And the namespace is gonna be similar, we'll call it Drupal\calculator\from. So this is going to be our namespace, that this is going to exist in which is going to become very important when we define the route for this in a few moments. Now a difference here that we're going to have is that when it comes to forms, there is what's known as a forms API within Drupal 8 that we are going to kind of tie into a little bit. And the way we are going to do that is we're gonna bring in some existing functionality that exists. Four forms within Drupal eight and we're gonna do that using the use keywords. So now I'm going to use some specifically defined classes that exist within Drupal in Drupal\Core\Form\FormBase. Now this is a base class that is we're going to extend in our implementation, that pretty much predefines what a form looks like, within the form's API. And what are the predefined functions that we need to implement, in order for this to truly become a form. And then we're also going to use a form state interface so that we can do some other interactions, that I'll show you a little bit later. But I'm gonna put this in their for now just so that it is there and we do not forget it for later. So we'll say FormStateInterface, okay? So we'll use that for later. So now we have this PHP file, now it's time for us to create our class, just like we did before. So we're gonna create a class and this is going to be our CalculatorForm. And as I said before there is some base functionality that exists in that predefined some functionality that we need to implement. So this is going to extend, or extends FormBase, just like that, and now here is our class. Now when it comes to forms there are four things that we need to implement so that this is going to be a valid form that we can use within our site. So that it kind of coincides with what a form is within the forms API within Drupal. The first thing that we need to implement is a function called Get Form ID. So this is gonna be public function getFormId. And this is nothing more than an identifier that we can use to identify this particular form. So you're typically going to want to name this something unique, something that you can easily remember and get access to that, kind of like I said, makes it unique throughout your application. So this is simply going to return a string, in this case we'll just call it my_calculator, and make it fairly simplistic. So that's all that's gonna need for the getFormId. The second thing that we are gonna need to actually implement, is going to be another function and this function is going to be buildForm. And we're gonna take in some information for this that we can use to actually build our form, and to get the current state of our form. So the first thing that we're gonna take in is an array called form and this is also gonna have a FormStateInterface, and we'll just call this $Form_state. So this is what the signature of the build form function looks like. So like I said before, we're gonna be taking in basically an associative array of a form that will allow us to define all the different inputs of that form. And then form_state, like I said before is for managing the current state of the form, which we're not gonna worry about as of yet. We're gonna use that in just a few moments. So now let's go ahead and just add in a couple of things for this particular form. So let's continue down the name example the greeting name example. And what I'd like to do now is I want to specify a text box, where the user can enter in their name that's gonna be required. They're gonna need to fill that in, that has a name of, or has some text like a label next to it. That says, please enter your name, something like that. So how do you do that, how do you add inputs to your form? Well, it's pretty simple. You specify the name of your array here in this case which is form with open and closed square brackets. Now within here you're going to define basically the Id, the identifier that you're going to be referring to this field later on within your application. So in this case, we will simply call this something like first_name. So that's what we're gonna refer to this as later on. So we're gonna set this equal to another array, and now within this array, we can specify different properties of this input, like what's the type of this input? What's the title or the label that's sitting next to it? Is it required, is it not required? Things of that nature. And remember, because we're dealing with Drupal 8, there's a lot of very special key value pairs that are in here. And so a lot of those special ones start with a hashtag, and these forms are no different. So the first thing that we want to define is going to be #type. So I wanna define what is the type of this particular input and this is going to be a textfield. Then I wanna define what is the label or the title that's gonna sit next to it so that the user knows exactly what they need to input in here. And in this case we are going to call this please enter your first name, something like that. So that's gonna be the text next to it and finally we wanna specify that this is actually required. So in order to that I can do #required, and we're gonna set that equal to true. So lets go ahead and say that. Now this is right to start your form this way, but the problem is there's no way to submit this form. So the final thing I wanna do in this case is I want to add a submit button. So I simply do the same process, I say form and I'm gonna call this submit is gonna be equal to another array. And within here I'm going to say that this is going to be a #type, and the type here is going to be a type submit, and the value is going to be set to Submit, just like that. Or you can call it something else, whatever you really like. So there we've built our form what's gonna have a single input field. Well, actually two input fields technically, because submit is an input field. But it's gonna have a text field and a button, to actually submit. So that's our build form. The next thing that we need to implement, and in this case we're not really gonna have to worry about it too much, is going to be validateForm. And we're gong to be doing basically the same thing, that we did before as far as the inputs are concerned. But the way that the inputs are defined in form base for this one is that this array is actually passed by a reference at this point, using the ampersand sign, which really means instead of sending a copy of the data of that form to the build form like we're doing here. We're actually sending the actual values here so that you can do things with it. You can modify it if you need to or what have you. In this case, we're not really going to worry too much about the validation, you might say, but we need to require this? Well, by the fact that we set this #required equal to true means that's gonna be handled for us. We really don't need to have too much logic in there. You can add something in if you want to do any sort of checking. But for that particular case I think we're gonna be just fine. Then the final piece of the puzzle that we are gonna need to do here is going to handle the submission of that form once the user actually hits the submit button. And that's gonna be handled by another function called submitForm. And then once again, we're gonna have our form and our form_state and this is once again here passed by reference like this so we'll go ahead and save that. And now within here, we can do whatever we would like to do with the information that was being passed to us after the user has filled it in and submitted it. But unfortunately at this point an obvious thing you might wanna do is do some sort of operation and present at the end user. But what I'd like to do Is take that name and then redirect the user over to my other route that we defined here, right here in order to handle that particular situation. But we haven't built that yet. So let's spend a little bit of time in the next lesson building out the rest of the routs for our application, and start to present something to the end user.