I have created a field_time_zone field for the Article content type. I want to set the allowed values for that field to the values returned from system_time_zones().

For this, I implemented hook_form_alter() using the following code.

$zones = system_time_zones();
$entityManager = \Drupal::service('entity_field.manager');
$fields = $entityManager->getFieldStorageDefinitions('node', 'local_market');
$options = options_allowed_values($fields['field_time_zone']);

if(empty($options)) {
$options =  $zones;
$form['field_time_zone']['widget']['#options'] = $options;

The code adds the desired values, but the node cannot be saved, as it throws the following error.

The value you selected is not a valid choice.

How can I set the allowed values for a text (list) field?


5 Answers 5


You can't do this in a form alter hook, because the entity field validation will fail.

You have to add a function to the field settings. This is not in the field UI, so you have to export the configuration and change the field in field.storage.node.field_time_zone.yml:

type: list_string
  allowed_values: {  }
  allowed_values_function: 'mymodule_allowed_values_function'

Reimport the configuration. Then you can implement this function in mymodule.module to set the options dynamically:

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\field\Entity\FieldStorageConfig;

  function mymodule_allowed_values_function(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable) {
    $options = [
    return $options;

See https://chromatichq.com/blog/dynamic-default-and-allowed-values-list-fields-drupal-8

For the question added later:

How can I set allowed value options to a field of type text(list) and save it accordingly?

The question originally was what to do with the code which doesn't work in form alter, where you can place it instead.

If you mean with this question you have a static allowed value list, then you can copy and paste the list in the field settings UI and save it:

enter image description here

And now it is stored in the mentioned yaml file of the exported configuration here:

  allowed_values: {  }
  • 2
    Note you would not even a callback if you just exported all allowed values. You only need the allowed_values_function callback if you need a dynamically computed list of allowed values.
    – Wim Leers
    Commented Aug 9, 2017 at 17:44
  • @WimLeers, yes, this is right. But this is not what my answer is about. The OP wanted to change the option list in a form alter hook. This is OK for normal forms, but doesn't work for entity forms. In this case you have to move the dynamic code to another place, see my answer or if it is static, put it in configuration, see your comment. Thank you for pointing this out.
    – 4uk4
    Commented Aug 9, 2017 at 20:24

After many hours i finally found solution. I dynamically created options for multi select field and got error message on submit that choosen select in wrong option.

It requires add new options to allowed_values for that field. Here is the solution:

 //load your field
 $field_purchasers = FieldStorageConfig::loadByName('user', 'field_xx');
 //subscribe new options to this field
$field_purchasers->setSetting('allowed_values_function','module_name_allowed_values_function' );
//save configuration

In your .module file write in callback function :

function module_name_allowed_values_function(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable) {
  $options = [
    1 => 'My new option 1',
    2 => 'My new option 2',
    3 => 'My new option 3',
  return $options;
  • That first part, why do like that, I think just modify the yml file with the function and re-import the config.
    – klidifia
    Commented Jun 10, 2019 at 1:07

For me getting the actual options and altering them did the work

$options = $form['field_name']['widget']['#options'];
$form['field_name']['widget']['#options'] = $options;

You should override the allowed values of the storage in your form alter:

// Retrieve the storage.
$fieldStorage = \Drupal\field\Entity\FieldStorageConfig::loadByName('node', 'local_market');

// Retrieve the current allowed field values.
$allowedValues = $fieldStorage->getSetting('allowed_values');

// Set your new allowed field values.
$allowedValues['field_time_zone'] = $zones;
$fieldStorage->setSetting('allowed_values', $allowedValues);

// Save.

Thanks, @Gun5m0k3. This works great. Here's a slightly adapted, more generic version.

In your form_alter:

// Define your options.
$my_options = ['foo' => 'foo', 'bar' => 'bar'];

// Add the options to the field widget.
$form['field_my_field']['widget']['#options'] = array_merge(

// Ensure that the new options are also added to the allowed_values list
$fieldStorage = \Drupal\field\Entity\FieldStorageConfig::loadByName('node', 'field_my_field');
$fieldStorage->setSetting('allowed_values', $my_options);

Is there a good reason why setting fieldStorage within a form_alter is a bad idea? It seems to work perfectly, so I wonder why this isn't the go-to solution as it's the easiest and most straightforward to implement.


  • 1
    The official way is to use the API of this module options.api.php (in /core/modules/options), which provides callback_allowed_values_function(). Saving a config entity involves a lot of overhead and might not be a good idea in normal page requests. That is why there is the API in the first place, to make such dynamic changes more efficient.
    – 4uk4
    Commented Jul 28, 2017 at 12:33
  • 1
    Changing config at run time is a bad practice not only for performance reasons, but also because it means your configuration is no longer reflecting reality. Which means you can't actually rely on your config anymore, and for example audits become meaningless. Plus, if you do change the allowed values in Field UI, that'd be automatically overwritten again.
    – Wim Leers
    Commented Aug 9, 2017 at 17:44
  • On top of that: if you interact with this entity via the PHP API or the REST API, and not via a form, it won't have this updated configuration. At least … not until you've used the form at least once.
    – Wim Leers
    Commented Aug 9, 2017 at 17:46
  • Finally: this is clearly a case of en.wikipedia.org/wiki/Side_effect_(computer_science), which is pretty much always going to haunt you :)
    – Wim Leers
    Commented Aug 9, 2017 at 17:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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