Perform alterations before a form is rendered.

Perform alterations before a form is rendered.

One popular use of this hook is to add form elements to the node form. When altering a node form, the node entity can be retrieved by invoking $form_state->getFormObject()->getEntity().

Implementations are responsible for adding cache contexts/tags/max-age as needed. See https://www.drupal.org/developing/api/8/cache.

In addition to hook_form_alter(), which is called for all forms, there are two more specific form hooks available. The first, hook_form_BASE_FORM_ID_alter(), allows targeting of a form/forms via a base form (if one exists). The second, hook_form_FORM_ID_alter(), can be used to target a specific form directly.

The call order is as follows: all existing form alter functions are called for module A, then all for module B, etc., followed by all for any base theme(s), and finally for the theme itself. The module order is determined by system weight, then by module name.

Within each module, form alter hooks are called in the following order: first, hook_form_alter(); second, hook_form_BASE_FORM_ID_alter(); third, hook_form_FORM_ID_alter(). So, for each module, the more general hooks are called first followed by the more specific.


ArchieV’s picture

Faced issue where I was needed to set multiple default values to multi-valued textfield.
Since you need to set default value per widget, you cannot just pass array of values as you did on D7.

My solution was:

$i = 0;
if ($i > 0) {
  $form['field_my_field']['widget'][$i] = $form['field_my_field']['widget'][0];
  $form['field_my_field']['widget'][$i]['#delta'] = $i;
  $form['field_my_field']['widget'][$i]['#weight'] = $i;
  $form['field_my_field']['widget'][$i++]['value']['#default_value'] = $id;
else {
  $form['field_my_field']['widget'][$i++]['value']['#default_value'] = $id;

So basically I just copy widget from first element, change delta and set default value. Stupid, but works.
Any better solution for that?

sjpagan’s picture

Hi, i'm trying to extract title of field in form_alter using drupal 8, how can I do ?
I see the data using kint


but it is protected

sasquatch_codes’s picture

You can get the $form['mail']['#title'] like so: kint($form['mail']['#title']->__toString()); and it'll return something along the lines of string(18) "Your email address". Also, the best thing you can do to figure out how to access a value is by looking at the Available Methods tab, that'll have a nice list of helpful methods for you.

itlakshman’s picture

I created field in my content type (training number), where i can hidden my number. but when i try to alter the title to (training code) in form alter unsuccessful. kindly suggest me in solution for form alter

nehapandya55’s picture

function digicare_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
   $user = \Drupal::currentUser();
   $uid = \Drupal::currentUser()->id();
   $roles = $user->getRoles();
   if (in_array('administrator', $roles) || in_array('admin_staff', $roles)) {
      if($form_id = "user_register_form"){
        /* for text field type value required false*/
	$form['field_first_name']['widget'][0]['value']['#required'] = 0;
	$form['field_last_name']['widget'][0]['value']['#required'] = 0;
	/* for select type value required false*/
	$form['field_gender']['widget']['#required'] = 0;
        /* for taxonomy type value required false*/
	$form['field_specializtaion']['widget'][0]['target_id']['#required'] = 0;
	$form['field_first_name']['#access'] = FALSE;
	$form['field_last_name']['#access'] = FALSE;
	$form['field_gender']['#access'] = FALSE;
	$form['field_specializtaion']['#access'] = FALSE;
drupalmonkey’s picture

From what I was seeing, if you set a custom form handler the way it shows in the example above:
$form['actions']['submit']['#submit'][] = 'mymodule_upload_enabled_types_submit';

The main submit handler for the form class (eg the submitForm method) on the form class you are altering will not run. You should set your custom form handler like so:
$form['#submit'][] = 'mymodule_upload_enabled_types_submit';

smooij’s picture

I just spent quite some time trying to reference my form id by using its machine name. With built in contact forms, you should reference contact_message_[MACHINENAME]_form. Also, if you are writing a hook for a specific built in contact form, use hook_form_contact_message_[MACHINENAME]_form_alter.

smooij’s picture

At least, this is the case for D8.

wtfbrb’s picture

Ok, so I spent most of a day trying to find how to use this to figure out how to programmatically set default values using this hook. Finally got it and figured I should share.

function teamlocal_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
    //throw new Exception('Oh no, an exception! ' . $form_id);
     if ($form_id == 'webform_submission_location_details_add_form') {
        $form['elements']['name']["#default_value"] = "blabla";
smooij’s picture

Agreed, better examples of usage should be provided.

liquidcms’s picture

To set Default Values:

textfield, number, etc:
$form['my_field']['widget'][0]['value']['#default_value'] = $my_value;

date field:
$form['my_field']['widget'][0]['value']['#default_value'] = DrupalDateTime::createFromTimestamp(strtotime('2018-02-21'));

list field:
$form['my_field']['widget']['#default_value'] = $key;
- i guess this is so different since list fields can never have cardinality > 1.