Skip to content

Instantly share code, notes, and snippets.

@ozin7
Last active August 11, 2022 16:32
Show Gist options
  • Save ozin7/d82cf590f2697d46f4543e62b551c8d0 to your computer and use it in GitHub Desktop.
Save ozin7/d82cf590f2697d46f4543e62b551c8d0 to your computer and use it in GitHub Desktop.
Drupal 8/9: Form with "Add more" ajax button
<?php
namespace Drupal\gurei\Form;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\State\StateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Class CategoriesSuggestionSettingsForm.
*/
class CategoriesSuggestionSettingsForm extends FormBase {
const CATEGORIES_SUGGESTION_KEY = 'gurei_categories_suggestion';
/**
* Categories.
*
* @var array
*/
protected $categories;
/**
* Term storage.
*
* @var \Drupal\taxonomy\TermStorageInterface
*/
protected $termStorage;
/**
* CategoriesSuggestionSettingsForm constructor.
*/
public function __construct(private StateInterface $state, EntityTypeManagerInterface $entityTypeManager) {
$this->termStorage = $this->entityTypeManager->getStorage('taxonomy_term');
$this->categories = $this->state->get(static::CATEGORIES_SUGGESTION_KEY);
$this->categories[] = '';
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('state'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritDoc}
*/
public function getFormId() {
return 'gurei_categories_suggestion_form';
}
/**
* {@inheritDoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
if (empty($form_state->get('categories'))) {
$form_state->set('categories', $this->categories);
}
else {
$this->categories = $form_state->get('categories');
}
$container_id = 'search-categories-suggestion';
$form['container'] = [
'#type' => 'fieldset',
'#title' => $this->t('Categories'),
'#tree' => TRUE,
'#attributes' => [
'id' => $container_id,
],
];
foreach ($this->categories as $delta => $category_id) {
$term = NULL;
if (!empty($category_id)) {
$term = $this->termStorage->load($category_id);
}
$form['container']['category'][$delta] = [
'#type' => 'entity_autocomplete',
'#default_value' => $term,
'#attributes' => [
'class' => ['container-inline'],
],
'#placeholder' => $this->t('Search by category name'),
'#target_type' => 'taxonomy_term',
'#selection_settings' => [
'target_bundles' => ['product_category'],
],
];
}
$form['container']['category_add'] = [
'#type' => 'submit',
'#value' => $this->t('Add more'),
'#submit' => [[self::class, 'addItem']],
'#ajax' => [
'wrapper' => $container_id,
'callback' => [self::class, 'ajaxRefresh'],
],
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Save'),
'#attributes' => [
'class' => [
'button--primary',
],
],
];
return $form;
}
/**
* Ajax callback.
*/
public static function ajaxRefresh(array &$form, FormStateInterface $form_state) {
$parents = $form_state->getTriggeringElement()['#parents'];
array_pop($parents);
return NestedArray::getValue($form, $parents);
}
/**
* Add new item on the form.
*/
public function addItem(array $form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$categories = $values['container']['category'];
$categories[] = '';
$form_state->set('categories', $categories);
$form_state->setRebuild();
}
/**
* {@inheritDoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$categories_to_save = [];
foreach ($values['container']['category'] as $category_id) {
if ($category_id) {
$categories_to_save[] = $category_id;
}
}
$this->state->set(static::CATEGORIES_SUGGESTION_KEY, $categories_to_save);
Cache::invalidateTags(['gurei.categories_suggestions']);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment