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? – 4k4 Apr 5 '17 at 19:17
  • I'm willing to use form alter hook, but I'm not sure how to do it there either – Matt Apr 5 '17 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/… – 4k4 Apr 5 '17 at 19:59

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'),

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.