26

I have the following routes in module_name.routing.yml.

module_name.usergroup_delete:
  path: 'module_name/usergroup/delete/{arg1}'
  defaults:
    _form: '\Drupal\module_name\Form\DeleteUserGroup'
    _title: 'Delete User group'
  requirements:
    _permission: 'access admin menus'

This is the code in module_name/src/Form/DeleteUserGroup.php.

namespace Drupal\module_name\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class DeleteUserGroup extends ConfigFormBase {

  public function getFormId() {
    return 'delete_user_group';
  }
/**
 * General form for switching all nodes from one user to another.
 */
  public function buildForm(array $form, FormStateInterface $form_state,$product_code) {
  $form['_product'] = array(
        '#type' => 'value',
        '#value' => $product_code,);
//get the user group and username to display the confirmation message 
$result = db_query('select field_p_group_name_value from {content_type_usergroup} ctu'       
        . ' where vid=%d',$product_code);      
    while ($row = $result->fetchObject()) {
      $user_group = $row->field_p_group_name_value;
    }

return confirm_form($form,t('Are you sure you want to delete "' .$user_group. '" User Group?'),
        isset($_GET['destination']) ? $_GET['destination'] : "function_name",t('This action cannot be undone.'),t('Delete'),t('Cancel'));

  }
/**
 * #submit callback for node_adoption_transfer_form().
 */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $form_values = $form_state->getValues();
  //if ($form_state['values']['confirm']) {
    $param = $form_state->getValue('_product');
    drupal_set_message(t('Group ' .$param.' will get deleted.'));               
    db_query('DELETE FROM {content_type_usergroup} WHERE vid = %d', $param);
    //delete the users of the usergroup too
    db_query('DELETE FROM {usergroup_user_map} WHERE group_id=%d', $param);
    drupal_set_message(t('usergroup has been deleted.'));
    drupal_goto('function_name');
  }

  protected function getEditableConfigNames() {
    return "delete_user_group";
  }

}

I am getting the following error:

DeleteUserGroup::buildForm() must be compatible with Drupal\Core\Form\FormInterface::buildForm(array $form, Drupal\Core\Form\FormStateInterface $form_state)

Why?

1
  • Can anyone explain how this equates when using the WebForm module? I have no module specifically for the form I have built using the module, so what would the point '_form' to within the routing.yml file ?
    – John Cogan
    Nov 6, 2017 at 13:40

3 Answers 3

45

The parameter has to have the same name in routing.yml and build method. And when using parameters in forms you have to set a null value in the parameter list:

public function buildForm(array $form, FormStateInterface $form_state, $arg1 = NULL) {
2
  • 4
    Ah yes! The additional parameters always have to be NULL to be compatible with Drupal\Core\Form\FormInterface::buildForm.💡
    – leymannx
    Mar 17, 2020 at 22:13
  • @leymannx I would be even concrete that additional parameters should be optional (nullable) with defaults like NULL, 'some_string', '2' and so on. See for example core/modules/comment/src/Form/CommentAdminOverview.php BTW: it is true for any method that follows interface where you want to add extra parameters. Feb 28, 2021 at 15:09
14

First create a routing.yml file

admin_notes.form:
  path: '/example_module/form/{arg}'
  defaults:
    _form: '\Drupal\example_module\Form\ExampleForm'
  requirements:
    _permission: 'access content'

Then create a .php file under folder structure /src/Form/ExampleForm.php .Then build a form

public function buildForm(array $form, FormStateInterface $form_state,$arg = NULL) {

             $form['example_note'] = array(
            '#type' => 'textarea',
            '#title' => t('Block contents'),
            '#description' => t('This text will appear in the example block.'),
            '#default_value' => $arg,
        );
       $form['actions'] = ['#type' => 'actions'];
        $form['actions']['delete'] = array(
            '#type' => 'submit',
            '#value' => $this->t('Delete'),
        );

return $form;
}
0
1

This is not asked in the question. Maybe it could also help, I had to pass a parameter to a form that was not loaded by a route. The form is integrated into a template loaded by a controller.

path: '/lorem/{arg}'
defaults:
    _controller: '\Drupal\my_module\Controller\LoremController::testLorem'

In the controller, the form is called and the parameter $arg is passed to the form builder.

public function testLorem($arg) {
    $form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\testForm', $arg);
}

And in the form :

public function buildForm(array $form, FormStateInterface   $form_state, arg = null) {
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.