Skip to content

Instantly share code, notes, and snippets.

@baikho
Last active August 23, 2022 09:34
Show Gist options
  • Save baikho/ec206f128eff4322e29a528f741adc74 to your computer and use it in GitHub Desktop.
Save baikho/ec206f128eff4322e29a528f741adc74 to your computer and use it in GitHub Desktop.
Drupal 8 Add More Ajax Form
<?php
namespace Drupal\example\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Class AjaxAddMoreForm.
*
* @package Drupal\example\Form
*/
class AjaxAddMoreForm extends ConfigFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'ajax_add_more_form';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'example.settings',
];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('example.settings');
$num = $form_state->get('num_items');
$wrapper_id = 'example-fieldset-wrapper';
$form['#tree'] = TRUE;
if ($num === NULL) {
$num = $config->get('example') ? count($config->get('example')) : 1;
$form_state->set('num_items', $num);
}
$form['wrapper'] = [
'#type' => 'fieldset',
'#title' => $this->t('Example Add More'),
'#prefix' => '<div id="' . $wrapper_id . '">',
'#suffix' => '</div>',
];
$form['wrapper']['example'] = [
'#type' => 'table',
'#header' => [
$this->t('Foo'),
$this->t('Bar'),
],
];
for ($i = 0; $i < $num; $i++) {
$form['wrapper']['example'][$i] = [
'foo' => [
'#type' => 'textfield',
'#default_value' => $config->get('example')[$i]['foo'] ?? NULL,
],
'bar' => [
'#type' => 'textfield',
'#default_value' => $config->get('example')[$i]['bar'] ?? NULL,
],
];
}
$form['wrapper']['actions'] = [
'#type' => 'actions',
];
$form['wrapper']['actions']['add'] = [
'#type' => 'submit',
'#value' => $this->t('Add one'),
'#submit' => [
[self::class, 'addOne'],
],
'#ajax' => [
'callback' => [self::class, 'ajaxCallback'],
'wrapper' => $wrapper_id,
],
];
if ($num > 1) {
$form['wrapper']['actions']['remove'] = [
'#type' => 'submit',
'#value' => $this->t('Remove one'),
'#submit' => [
[self::class, 'removeOne'],
],
'#ajax' => [
'callback' => [self::class, 'ajaxCallback'],
'wrapper' => $wrapper_id,
],
];
}
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this
->config('example.settings')
->set('example', $form_state->getValue('wrapper')['example'] ?? [])
->save();
parent::submitForm($form, $form_state);
}
/**
* Callback for both ajax-enabled buttons.
*/
public function ajaxCallback(array &$form, FormStateInterface $form_state) {
return $form['wrapper'];
}
/**
* Submit handler for the "add one" button.
*/
public function addOne(array &$form, FormStateInterface $form_state) {
$form_state
->set('num_items', $form_state->get('num_items') + 1)
->setRebuild();
}
/**
* Submit handler for the "remove one" button.
*/
public function removeOne(array &$form, FormStateInterface $form_state) {
if ($form_state->get('num_items') > 1) {
$form_state
->set('num_items', $form_state->get('num_items') - 1)
->setRebuild();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment