DEV Community

Krystian Podemski
Krystian Podemski

Posted on • Edited on

PrestaShop: adding new fields to the customer form

In this article, I will demonstrate how to edit, add, and modify fields available in the customer form, in PrestaShop.


One of the users of a popular Polish PrestaShop group on Facebook did not manage to modify the form fields available during the registration process. His task was to alter the "optin" field. He wanted to change both the content and style of the field.

Code from this article will work with PrestaShop 1.7.7 and above versions.

With help comes the "additionalCustomerFormFields" hook. Since PrestaShop version 1.7.7, it got the &$fields parameter, which contains a whole array of fields used to create a registration form.

This article describes how we can use it.

How does it work?

As in many other places in the system, we have a parameter that is available as a reference (here's a more detailed explanation of what references are), thanks to that, we can operate with the data freely, and we will apply our modifications after calling this Hook.

To get started, we need, of course, to hook to the appropriate place in the code in our module.



public function install()
{
    return parent::install() && $this->registerHook('additionalCustomerFormFields');
}


Enter fullscreen mode Exit fullscreen mode

In our module, we have access to the entire array of fields in the method that handles the hook. You can dump them, like this:



public function hookAdditionalCustomerFormFields($params)
{
    $format = $params['fields'];
    dump($format);
}


Enter fullscreen mode Exit fullscreen mode

If we go to the registration page at this point, we will see all the fields:

form fields dump PrestaShop

The rest is just a formality. Let's move on to the real-world use of hookAdditionalCustomerFormFields.

Adding fields

Each field is an instance of FormField. This is a class available globally in the system. We can add a new field like this:



public function hookAdditionalCustomerFormFields($params)
{
    $format = $params['fields'];
    $format['confirmation_email'] = (new FormField())
        ->setName('confirmation_email')
        ->setType('email')
        ->setLabel($this->trans('Confirm your e-mail address', [], 'Modules.Demooverridecustomerformatter.Front'))
        ->setRequired(true);
    $params['fields'] = $format;
}


Enter fullscreen mode Exit fullscreen mode

This way, we added a new field to the form. This field called "confirmation_email" is a typical example of adding an element to force the buyer to confirm their email address.

Deleting fields

If we want to make any of the fields no longer available in the form, we can remove them using PHP's unset. Example:



public function hookAdditionalCustomerFormFields($params)
{
    $format = $params['fields'];
    unset($format['id_gender']);
    $params['fields'] = $format;
}


Enter fullscreen mode Exit fullscreen mode

Modifying existing fields

Let's see how we can modify fields, which the author of the thread on Facebook cared about. How to change the fields? Let's focus on the optin field. Let's modify its label and add a style (although this is not something we should do in this application layer).



public function hookAdditionalCustomerFormFields($params)
{
    $format = $params['fields'];
    $newLabel = '<em class="text-warning">';
    $newLabel .=    $this->trans(
        'I want to receive free gift from your partners',
        [],
        'Modules.Demooverridecustomerformatter.Front'
    );
    $newLabel .= '</em>';
    $format['optin']->setLabel(
        $newLabel
    );
    $params['fields'] = $format;
}


Enter fullscreen mode Exit fullscreen mode

As we can see, by having access to an instance of a field, we can use methods available in the FormField class, one of them is setLabel.

We added em, color and changed the text, the effect is as follows:

example of modified customer form in PrestaShop

Summary

As we can see, modifying the registration form fields using a dedicated Hook is quite accessible and allows developers to have complete control over it. As the fields are an array, we can freely modify them, change their order, delete and add new ones.

This article did not cover all the issues related to the registration form and its fields, I did not show how to receive the values sent from the additional fields, verify and possibly save them in the database. There will be time for that at another time.

If you have any questions, let me know :-)

Top comments (3)

Collapse
 
jromero-onclick profile image
Jordi Romero • Edited

It exists another hook called 'hookActionCustomerFormBuilderModifier' that receives a parameter called form_builder and it is an instance of CustomerFormBuilder.
Using the builder, you can add, remove o get all fields of the customer form.
In order to sort the fields in the order you want, you can get all fields with the method $formBuilder->all(), then remove all the fields, and create again with a foreach, and taking care of adding your new custom field where you want.
Examples:
/** @var FormBuilderInterface $formBuilder */
$formBuilder = $params['form_builder'];

    // remove first_name field
    $formBuilder->remove('first_name');

    // get all fields without removed
    $allFields = $formBuilder->all();

    foreach ($allFields as $inputField => $input) {
        // add fields
        $formBuilder->add($input);
   }

        // add fields after gender_id
        if ($inputField == 'gender_id') {

            $formBuilder->add('first_name', TextType::class, [
                'label' => $this->trans('First name', [], 'Admin.Global'),
                'help' => $this->trans(
                    'Invalid characters:',
                    [], 
                    'Admin.Notifications.Info'
                ) . ' ' . TypedRegexValidator::GENERIC_NAME_CHARS,
                'required' => true,
                'constraints' => [
                    new NotBlank([
                        'message' => $this->trans(
                            'This field cannot be empty.', [], 'Admin.Notifications.Error'
                        ),
                    ]),
                    new CleanHtml(),
                    new TypedRegex([
                        'type' => TypedRegex::TYPE_GENERIC_NAME,
                    ]),
                    new Length([
                        'max' => FirstName::MAX_LENGTH,
                        'maxMessage' => $this->trans(
                            'This field cannot be longer than %limit% characters',
                            ['%limit%' => FirstName::MAX_LENGTH],
                            'Admin.Notifications.Error',
                        ),
                    ]),
                ],
            ]);     
Enter fullscreen mode Exit fullscreen mode

}

Collapse
 
david_bbd14cac profile image
David Jonas

Thanks for the blogpost, this is much better information than the official documentation. Unfortunately, I still do not manage to solve my problem with it. Do you know how to determine the order of the fields? I am trying to place a custom field between the core fields. And also is there a best practice on how to store the data in the database?

Collapse
 
moa profile image
Mohamed Akhelij

Thanks for the blog, I wonder if there is a way to define where to place the added fields.