There should be a way for a field to set a default value in its own way, i.e. not as a pre-determined, hard-coded value. For instance, Date has to set a default value at the time the entity is created, because it's usually a relative value. In D6 we had a way for a module to create a 'default_value' function that would get called. That got lost in D7 and there is currently no way that I have been able to find for a field to set a default value normally. I found a work-around in D7 that used hook_widget_properties_alter(). That also worked in D8 until the latest round of changes that removed that hook, and I'm back to having no way to set a default value.

There may be some way to do this that I'm missing, but so far I'm coming up empty and help would be appreciated. I suspect it is a bug, but maybe it's a support question.

Comments

arlinsandbulte’s picture

Title: No way for a field to set its own default value » No way for a field to dynamically set default value

Slightly better title, I think.
I don't think this is or should be unique to date fields, but I cannot think of another use case either.

In short, a date field needs to be able to dynamically set its default value to now() or some value relative to now().

IMO, this might even qualify as major, but I will let some one else make that call.

KarenS’s picture

Here is the problem, both in D7 and D8:

The field code is set up to look for $instance['default_value_function'], and if that exists, use that function to create the default value.

If you create a field using CRUD and manually add that value to the $instance, it works.

However, there is no way for a module like Date to get that value into the instance. We have hook_field_info() and hook_widget_info(). Neither of them set values on the $instance. You can put a value into $field['settings'], $field, $widget, or $widget['settings'], but there is no way to put a value into $instance using the info hooks.

That leaves hook_field_widget_properties_alter() as the only recourse. And it turns out that that fires after the default value has been evaluated.

Hence there is no way for a module to define a default value function for its widget.

I actually wasn't using the hook to set a default function, I was using it to check the entity to see if it was new and set a flag for my post-processing. I was wrong about the hook being removed. It's still there. But it used to have the $entity passed in and that is no longer true, which broke my hacky work-around.

The real fix that is needed is to make it possible to add the default value function to the $instance. Now that we have the new OO handling, maybe I can find some way to get it in there. But really the code should not make this so hard to do :(

HnLn’s picture

I had a need for this as well. My use case was an entity reference field where the default value needed to be populated by a nodequeue. I ended up using _field_attach_form and jump through multiple hoops to reset the field_state (with field_form_get_state) and got something working.

In general I can imagine a lot of use cases where you want the default value to be depending on a certain context.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ziodave’s picture

Issue summary: View changes

I resorted to creating widgets (extending the base widgets), whose only concern is to set the default value dynamically according to contextual values, e.g. I have a widget that presets a default value to an entity name referenced by the logged in user, something like this:

/**
 * Define the {@link AcmeWidget} class.
 *
 * @FieldWidget(
 *   id = "acme_widget",
 *   label = @Translation("Acme Textfield"),
 *   field_types = {
 *     "string"
 *   }
 * )
 *
 * @package Drupal\acme\Plugin\Field\FieldWidget
 */
class AcmeWidget extends StringTextfieldWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

    // Call our parent but set the value using our default value function.
    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    // Get the current user organization's name.
    $user = User::load(\Drupal::currentUser()->id());
    $organization = $user->get('field_organization')->entity->title->value;

    // Set the default value if a value hasn't been set.
    $element['value']['#default_value'] = $organization;

    return $element;
  }


}

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

noktorn’s picture

In D7, this can work as follows:

hook_form_alter

$form['field_name']['und'][0]['value']['#default_value'] = array($value);

But this does not work in D8:

hook_form_alter

$form['field_name']['widget'][0]['value']['#default_value'] = $value;

And this, too, does not lead to any result:

unset($form['field_name']['widget'][0]['value']['#default_value']);

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

akalata’s picture

This issue may no longer be valid, as there are ways to set default value callbacks on field instances:

  1. Using BaseFieldDefinition->setDefaultValueCallback()
  2. Using hook_entity_bundle_field_info_alter():
      if ($entity_type->id() == 'my_entity' && $bundle == 'my_bundle' && !empty($fields['field_my_field'])) {
        $fields['field_my_field']->setDefaultValueCallback('my_default_field_callback');
      }
    
  3. Directly editing the field instance's config file as described at https://chromatichq.com/blog/dynamic-default-and-allowed-values-list-fie..., for example updating field.field.my_entity.my_bundle.my_field to include
    default_value_callback: 'my_default_field_callback'
amateescu’s picture

Status: Active » Closed (outdated)

#12 is spot on! Also, field types now have a way to provide default values globally in their item list's applyDefaultValue() method.