0

I have a form:

public function buildForm(array $form, FormStateInterface $form_state)
  {
    // Disable caching on this form.
    $form_state->setCached(FALSE);

    $scheme_data;
    // code to get select options removed for legibility

    $form['scheme'] = [
      '#type' => 'select',
      '#title' => $this->t('Select an organisation'),
      '#options' => $scheme_data,
      '#empty_option' => $this->t('Select an organisation'),
      '#ajax' => [
        'callback' => [$this, 'choseSchemeOption'],
        'event' => 'change',
        'wrapper' => 'scheme-option',
      ],
    ];

    $form['scheme-option']['option-query'] = [
      '#type' => 'container',
      '#attributes' => ['id' => 'option-query'],
    ];

    $formTrigger = $form_state->getTriggeringElement();
    if (is_array($formTrigger)) {
      switch ($formTrigger['#name']) {

        case 'scheme':
            $option_data = $this->buildQueryselect($form_state, true);
            $form['scheme-option']['option-query'] = [
                '#type' => 'select',
                '#title' => $this->t('Tell us more about your query'),
                '#empty_option' => $this->t('Select an option'),
                '#options' => $option_data,
                '#ajax' => [
                  'callback' => [$this, 'choseQuery'],
                  'event' => 'change',
                  'wrapper' => 'option-query',
                ],
              ];
          }

          break;           

        case 'option-query':
          $option_data = $this->buildQueryselect($form_state);
          $form['scheme-option']['option-query'] = [
            '#type' => 'select',
            '#title' => $this->t('Tell us more about your query'),
            '#empty_option' => $this->t('Select an option'),
            '#options' => $option_data,
            '#ajax' => [
              'callback' => [$this, 'choseQuery'],
              'event' => 'change',
              'wrapper' => 'option-query',
            ],
          ];
          break;
      }
    }


    return $form;
  }

  public function choseSchemeOption(array &$form, FormStateInterface $form_state)
  {
    return $form['scheme-option'];
  }

  public function choseQuery(array &$form, FormStateInterface $form_state)
  {
    return $form['scheme-option']['option-query'];
  }
  private function buildQueryselect($form_state, $reset = false)
  {
  // ..returns select options
  }

When the scheme select changes, the option-query updates to the correct options. When I change the option-query selected option, I want its options to change based on the value selected.

If I debug and watch the variables, $option_data is updated to what I am expecting, but the front end select options do not.

I have also tried commenting out the switch "case 'option-query':" in buildForm() and updated the ajax callback:

  public function choseQuery(array &$form, FormStateInterface $form_state)
  {
    $option_data = $this->buildQueryselect($form_state);
    $form['scheme-option']['option-query']['#options'] = $option_data;
    return $form['scheme-option']['option-query'];
  }

But that also failed to achieve the desired result. It also started generating "Illegal choice xx in Tell us more about your query element." errors when selecting an option after the first attempt.

What do i need to do to replace the options in the select that is calling the ajax callback? I don't want to replace the options in a different form element which the examples I have seen to far have demonstrated.

Thank you for your help.

2
  • In the switch case you're replacing the option-query element, but not adding the ID attribute back in. So 2nd time round there's no element with the ID Drupal is looking for to replace the content with. Your first approach was right by the way, the options need to be set in the form builder, not the AJAX callback (that's probably why you're seeing the "illegal choice" error)
    – Clive
    Apr 3 '19 at 18:03
  • ah, I see, yes, the container with id='option-query' is replace with the select. Added '#prefix' => '<div id="option-query">', '#suffix' => '</div>', to $form['scheme-option']['option-query'] and I can now update the select. Thank you! If you would like to make this into an answer, I'll mark it as such?
    – ice70
    Apr 4 '19 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.