drupal-8drupal-modulesdrupal-forms

Create custom module for render custom forms through a controller in Drupal 8


I need to render a custom form which is created using Drupal\Core\Form\FormBase and Drupal\Core\Form\FormStateInterface through a controller in custom Drupal 8 module. Is there any guidence or reference to follow to do this?

Actually I tried to render form directly and through a controller. But both ways are not working. Only render the submit button. I refer the drupal 8 documentation also. But I couldn't find a solution for this. Please be kind enough to find my coding samples below. If there are anything wrong. Please correct me.

my_module.routing.yml

partner.content:
    path: '/partner'
    defaults:
        _controller: '\Drupal\partner\Controller\PartnerController::add'
        _title: 'Add Partner'
    requirements:
        _permission: 'access content'

partner.addform:
    path: '/partner/add'
    defaults:
        _form: '\Drupal\partner\Form\AddForm'
        _title: 'Add Partner'
    requirements:
        _permission: 'access content'

AddForm.php

namespace Drupal\my_module\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class AddForm extends FormBase
{
    /**
     * Returns form id
     *
     * @return string
     */
    public function getFormId(): string
    {
        return 'my_module_add_form';
    }

    /**
     * Build form array
     *
     * @param array $form
     * @param FormStateInterface $formState
     * @return array
     */
    public function buildForm(array $form, FormStateInterface $form_state): array
    {
        // First name
        $form['first_name'] = [
            '#type'     => 'textField',
            '#title'    => t('First Name'),
            '#required' => true,
        ];

        // Other input fields...

        $form['submit'] = array(
            '#type' => 'submit',
            '#value' => $this->t('Save Changes'),
            '#button_type' => 'primary',
        );

        return $form;
    }

    public function validateForm(array &$form, FormStateInterface $form_state) {}

    public function submitForm(array &$form, FormStateInterface $form_state) {}
}

MyModuleController.php

<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\my_module\Form\AddForm;

class MyModuleController extends ControllerBase
{
    public function add()
    {
        $addForm = new AddForm();
        $form    = \Drupal::formBuilder()->getForm($addForm);

        return [
            '#theme' => 'form_my_module_add',
            '#form'  => $form,
        ];
    }
}

Solution

  • Happy to find out the solution with Hemantha Dhanushka on my comment.

    To make it clear this question has a correct answer, here I past the validated comment.

    I would recommend you to use the first approach (using routing::_form instead of Controller). Also, it seems you use the wrong #type for your first_name field. Try textfield instead of textField.


    Also, for people who want to go further, here are some links to implement a proper routing::_form approach to expose a form as a page instead of using a Controller: https://www.valuebound.com/resources/blog/step-by-step-method-to-create-a-custom-form-in-drupal-8.

    For people looking for more help about existing Form Element Reference (textfield, checkboxes, entity_autocomplete, ...) here is an excellent up-to-date article https://drupalize.me/tutorial/form-element-reference?p=2766