0

In my case, I need to get a list of config files to show in a form element. Extending from this Drupal Answers Q/A using form_state->set() inside ajax callback but cannot get the value back outside the callback, I see a suggested way of calling a static function in the submit.

However, I am missing some understanding of how to properly execute.

$list = '';

$form['fieldset'] = [
  '#type' => 'fieldset',
  '#prefix' => '<div id="wrapper">',
  '#suffix' => '</div>',
];

$form['fieldset']['list'] = [
  '#type' => 'item',
  '#title' => t('List'),
  '#description' => $list,
];

$form['fieldset']['submit'] = [
  '#type' => 'submit',
  '#value' => $this->t('Submit'),
  '#submit' => [static::class, 'customFunction'],
  '#ajax' => [
    'callback' => '::customCallback',
    'wrapper' => 'wrapper',
  ],
];

public function customCallback(array &$form, FormStateInterface $form_state) {
  $list = $form_state->get('list');
  $form_state->setRebuild(TRUE);
}

public static function customFunction(array &$form, FormStateInterface $form_state) {
  $form_state->set('list', $li);
}

How does one get $form_state value into a form element from an ajax button submit function?

Update:

Here is what I have working for this case thanks to @No Sssweat.

public function buildForm(array $form, FormStateInterface $form_state) {

  $form['fieldset']['list'] = [
    '#type' => 'item',
    '#title' => t('List'),
    '#description' => '',
  ];

  $form['fieldset']['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Submit'),
    '#submit' => [static::class, 'customFunction'],
    '#ajax' => [
      'callback' => '::customCallback',
      'wrapper' => 'wrapper',
    ],
  ];

}

public function customCallback(array &$form, FormStateInterface $form_state) {

  $values = $form_state->getValues();
  $li = [];
  $config_path = drupal_get_path('module', $values['fieldset']['module_name']) . $values['fieldset']['directory_path'];

  if (is_dir($config_path)) {
    if ($dh = opendir($config_path)) {
      while (($fileName = readdir($dh)) !== false) {
        if (pathinfo($fileName, PATHINFO_EXTENSION) == 'yml') {
          $fileName = str_replace('.yml', '', $fileName);
          $li[] = $fileName;
        }
      }
      closedir($dh);
    }
  }

  $markup = new TranslatableMarkup(
    '<ul>@li</ul>', [
      '@li' => t('<li>' . implode('</li><li>', $li) . '</li>'),
    ]
  );

  $form['fieldset']['list']['#description'] = $markup;
  return $form['fieldset'];
}

public static function customFunction(array &$form, FormStateInterface $form_state) {
  // Empty.
}

But this avoids the question as asked.

2

Should be:

public function customCallback(array &$form, FormStateInterface $form_state) {
  $list = $form_state->get('list');
  $form['fieldset']['list']['#description'] = $list;
  return $form['fieldset'];
}
  • 1
    Yes, this is the correct answer. The ajax callback has to return either $form or an ajax response. But it shouldn't modify $form, this should have been done already in the form build. – 4k4 May 8 at 7:06
  • I've added to my question. I could not get ->set/->get to work through the custom functions. Could this be because of the $form['fieldset']['list'] element type? – Prestosaurus May 8 at 17:53
  • @Prestosaurus it's because '#type' => 'item',. Item type does not have a value. If you set it to '#type' => 'textfield', and then put some text on the text-box, you should see the description change to that after ajax. – No Sssweat May 9 at 8:01

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.