I'm currently rendering a contact form programmatically in a block plugin like so.

    $type = 'contact_message';
    $bundle = 'my_contact_form_name';
    $values = array();
    if (\Drupal::entityManager()->getDefinition($type)->hasKey('bundle')) {
        $bundle_key = \Drupal::entityManager()->getDefinition($type)->getKey('bundle');
        $values     = array($bundle_key => $bundle);
    $entity = \Drupal::entityManager()

    if ($entity instanceof EntityOwnerInterface) {

    $form = \Drupal::entityManager()
        ->getFormObject($type, 'default')

    $my_rendered_form = \Drupal::formBuilder()->getForm($form);
        $content[] = [
            '#type'    => 'html_tag',
            '#tag'     => 'h1',
            '#value'   => 'My Form Title',
            'form'    => $my_rendered_form,

It grabs and renders the form just fine. But the form has a select field and I want to alter the options for it. This is because the options should be dynamically generated based off the values of certain nodes. I already have a field called 'my_select_field' but I'm not sure how to change the values from it. When using die(print_r($my_rendered_form['my_select_field'])); I receive a very large array and the my_select_field, and the test data I put in it appears in many locations in the array. My ultimate goal would be to accomplish something like this

$form['my_select_field']['#options'] = [
    1 => 'My new option 1',
    2 => 'My new option 2',
    3 => 'My new option 3',

How would I alter the options in a select field in a programmatically rendered contact form?

UPDATE: I found '#options' in the array

        [#options] => Array
                [test1] => Drupal\Core\Field\FieldFilteredMarkup Object
                        [string:protected] => Test 1

                [test2] => Drupal\Core\Field\FieldFilteredMarkup Object
                        [string:protected] => Test 2

                [test3] => Drupal\Core\Field\FieldFilteredMarkup Object
                        [string:protected] => Test 3

                [test4] => Drupal\Core\Field\FieldFilteredMarkup Object
                        [string:protected] => Test 4


But the options are objects rather than strings I can edit. I should probably also mention that the select field I have is set to multiple checkboxes.

EDIT: I'm willing to use a form alter hook if that is necessary. But if that's the case the same question applies.

UPDATE 2: I attempted altering the form using the hook form alter method like so

        $form['my_select_field']['widget']['#options'] = [
            1 => 'New option 1',
            2 => 'New option 2',

And the new options do appear, but now when I submit the form I receive the error

The value you selected is not a valid choice.

  • You can't do this after the form is built, you can only submit options that are processed by the form builder. Otherwise you get the error "An illegal choice has been detected. Please contact the site administrator." Did you try to use a form alter hook?
    – 4uk4
    Apr 5, 2017 at 19:17
  • I'm willing to use form alter hook, but I'm not sure how to do it there either
    – Amy
    Apr 5, 2017 at 19:17
  • I think this is a slightly different error, not from form api, but from entity validation. But as contact forms are entity forms that seems logical. In this case you need to follow this tutorial chromatichq.com/blog/…
    – 4uk4
    Apr 5, 2017 at 19:59

1 Answer 1


This is probably not a good use case for the core version of contact form based on entity forms. You have not only to take care of the validation in the form api, but also on the entity level. If you want to do this, here is a tutorial: https://chromatichq.com/blog/dynamic-default-and-allowed-values-list-fields-drupal-8

In contrast Webform provides a very flexible handling of select options. You can edit the options separately from the form in predefined options lists and then you can modify the predefined options dynamically, see these examples:

 * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().

function mymodule_webform_options_test_alter(array &$options, array &$element) {
  $options += [
    'four' => t('Four'),
    'five' => t('Five'),
    'six' => t('Six'),

 * Implements hook_webform_options_alter().
function mymodule_webform_options_alter(array &$options, array &$element, $id) {
  if ($id == 'custom') {
    $options = [
      'one' => t('One'),
      'two' => t('Two'),
      'three' => t('Three'),
  • The method in the linked tutorial will not work if there are contact form submissions already.
    – ummdorian
    Sep 1, 2021 at 21:51

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.