12/1/2021

Drupal 8 Custom Service

Creating forms is part of the day to day live of a Drupal programmer. Forms are represented as nested arrays in both Drupal 7 and Drupal 8. But they are different in that in Drupal 7 you define your form arrays in functions and in Drupal 8 you create a form class.

We are going to be learning Drupal 8 service dependency injection and we are going to be building on top of the module that we created in a previous video. Dependency Injection enables us to decouple reusable functionality by injecting it, rather than creating it inside of a class (in our case service class). Create a Service on Drupal 8. Create a custom module (here: mymodule) name: 'My Module' description: 'Custom Module' package: Custom type: module core: 8.x 2. Create service file and add the class as service Example: mymodule.services.yml. I need to inject a currentuser service to get data about current user. Services: mymodule.custom. I am new to Drupal 8 development and trying to ensure I am following the best practices, but at the same time I don't want to overcomplicate things. 8 services page-controller. Improve this question. Can I get dependent services into a custom class without creating a service?

In this post we’ll create a custom form with two fields, a text field and a checkbox field, we’ll validate those fields, display them in a message and finally redirect the user to the home page.

You can find the code of this module here.

Here is a screenshot of the form:

You can see the folder structure of this module below:

First we’ll create the form step by step manually, then we’ll use Drupal Console to do it in a easier way.

1. Create the module’s skeleton
2. Create the form’s class and assign a name to the form
3. Build the form
4. Validate the form
5. Process the collected values
6. Add a route to your form
7. Do it easier with Drupal Console

In Drupal 8, each form is defined by a controller class that implements the interface DrupalCoreFormFormInterface which defines four basic methods:

getFormId() - Defines the unique ID for the form
buildForm() - Triggered when the user requests the form. Builds the basic $form array with all the fields of the form.
validateForm() - Triggered when the form is submitted. It’s used to check the values collected by the form and optionally raise errors.
submitForm() - Used to carry out the form submission process, if the form has passed validation with no errors.

Drupal 8 Custom Service Center

Drupal 8 Custom Service

1. Create the module’s skeleton

As always, we use the Drupal Console to create the module. Don’t forget to install the module after it has been generated.

We use the following command:

Service

Once created we can install it with drupal module:install ex81 command

2. Create the form’s class

We create a new php file called HelloForm.php in the src/Form folder. In this file we create a new class called HelloForm that extends the abstract class FormBase (which implements the FormInterface interface).

In this class we create the getformId() method to set a unique string identifying the form.

3. Build the form

Now we add to this class a new method called buildForm() which defines the text and the checkbox fields of our form. We also add a field description to add a small message on top of the form.
At the end of the method we add a submit field and return the form array.

4. Validate the form

To validate the form we just need to implement the validateForm() method from DrupalCoreFormFormInterface in our HelloForm class.

In our example we’ll raise an error if the length of the title is less than 10 and also if the checkbox is not checked. User-submitted values can be accessed via $form_state->getValue('key') where 'key' is the name of the element whose value we would like to retrieve.

We raise an error thanks to the setErrorByName() method of the $form_state object.

5. Process the collected values

Now it’s time to process the values collected by our form. We do this with the submitForm() submission handler method.

Here we can save the data to the database, send them to an external API or use them in a service. In our case we’ll just display those values and redirect the user to the home page. To redirect the user, we’ll use the setRedirect() method of the $form_state object.

Remember that if you need to save those values in the config system, you should extend the ConfigFormBase as we saw earlier in another post.

6. Add a route to your form

Now that we have added a controller to your custom module, we are almost done. The last thing is to add a route in our routine file in order to allow users to access our form.

If we haven’t created this file before, we create the ex81.routing.yml file in the root of the module. In this file we add the route that points to the form controller (HelloForm) we created above. In this case we won’t be using the _controller key, but the _form key, so Drupal will use the form builder service when serving this request.

The above code adds a route that maps the path /ex81/helloform to our form controller Drupalex81FormHelloForm.

Now we can navigate to our form and test it!

Recap.
1. We created the module with the Drupal Console command: drupal generate:module
2. We created the form controller class HelloForm in the srcForm folder. This class extends the abstract class FormBase that implements the interface FormInterface.
3. We set a unique string ID for our form with the getFormId() method.
4. We defined the fields of the form with the buildForm() method.
5. To validate the form, we used the validateForm() method and use the setErrorByName() method of the $form_state object.
6. We processed the values of the form with the submitForm() method and redirect the user to the home page with the setRedirect() method of the $form_state object.
7. We created a route that points to our form using the specific key _form

7. Bonus: Create a custom form with Drupal Console

We’ll create the same form as above but in another module called 'ex82'.

Now we’ll create the form with a simple Drupal Console command: drupal generate:form

This will generate two files, HelloForm.php and ex82.routing.yml, as you can see Drupal Console generate almost the entire form.

Drupal 8 Custom Search Page

Let’s take a look at the new generated HelloForm.php

First you can see that we voluntary inject the messenger service in the Drupal Console command, this allows us to avoid calling the Static Service Container wrapper Drupal::messenger(). We’ll use it in the buildForm() method later.

Now, we’ll need to add the code for the validation and the submit process with:
- validateForm() method
- submitForm() method

You can copy the same code of the validateForm() method described above in this post in the section 4.

For the buildForm() method we’ll use the same code as above but with a small change since we injected the messenger service

As simple as that. YES! Drupal Console is definitively a great tool to create custom forms!!!

More info:

ServiceServices

Introduction to Form API (Drupal Doc)
Drupal 8 Form API reference
Drupal 8 Development Solutions : Creating a Form [VIDEO]

Related Content

View the discussion thread.

Drupal 8 service dependency injection in our custom module

We are going to be learning Drupal 8 service dependency injection and we are going to be building on top of the module that we created in a previous video.

Dependency Injection enables us to decouple reusable functionality by injecting it, rather than creating it inside of a class (in our case service class).

In order to find all the services that we have from Drupal 8 core - we could just search for a service on this page. There we will find the current user service. In order to inject it into our service we just have to take the service name and pass it as an argument in the .services.yml file like this:

and then in our service class we just have to get the service in the __construct method and store it in a local variable like this:

and then we could use the current user service and get the display name of the current logged in user in the whoIsYourOwner method.

The full code of the module you may find here.

View the discussion thread.