Temps de lecture
Environ 3 minutes
Ce bout de code fait la démonstration de l'utilisation de la class FormBase afin d'implémenter à un élément de Form la fonctionnalité - ajouter un élément - ou - retirer cet élément - en ajax.
<?php
namespace Drupal\module_name\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements the ajax add and remove item form controller.
*
* This example demonstrates using ajax callbacks to add people's names to a
* list of picnic attendees.
*
* @see \Drupal\Core\Form\FormBase
* @see \Drupal\Core\Form\ConfigFormBase
*/
class AjaxAddMoreAndRemoveOneForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'ajax_addmore_andremove_one_form';
}
/**
* Form with 'add more' and 'remove this' buttons.
*
* This example shows a button to add another textfield, and
* a bouton "remove this" to delete specific items.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Gather the number of items in the form already.
// We need a element to started
$num_names = $form_state->get('num_names');
// We need a element to started, if not, set it
if ($num_names === NULL) {
$num_names = $form_state->set('num_names', [1]);
$num_names = $form_state->get('num_names');
}
// No cache please
$form['#cache'] = ['max-age' => 0];
// Mode tree for better experience return $form_state
$form['#tree'] = TRUE;
// Start stuff with a description
$form['description'] = [
'#type' => 'item',
'#markup' => $this->t('This example shows an add-more and a remove this item button.'),
];
$form['names_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this->t('People coming to picnic'),
'#prefix' => '<div id="names-fieldset-wrapper">',
'#suffix' => '</div>',
];
// Loop needed items form
foreach ($num_names as $key) {
$form['names_fieldset'][$key]['name'] = [
'#type' => 'textfield',
'#title' => t('Name'),
];
$form['names_fieldset'][$key]['forname'] = [
'#type' => 'textfield',
'#title' => t('Forname'),
];
// No bouton remove for the first element
if ($key != 1) {
$form['names_fieldset'][$key]['remove_name'] = [
'#type' => 'submit',
'#value' => t('RM ' . $key),
'#submit' => ['::removeCallbackOne'],
'#ajax' => [
'callback' => '::addmoreCallback',
'wrapper' => 'names-fieldset-wrapper',
],
];
}
}
// Action
$form['names_fieldset']['actions'] = [
'#type' => 'actions',
];
// Add
$form['names_fieldset']['actions']['add_name'] = [
'#type' => 'submit',
'#value' => t('Add one more'),
'#submit' => ['::addOne'],
'#ajax' => [
'callback' => '::addmoreCallback',
'wrapper' => 'names-fieldset-wrapper',
],
];
// cache FALSE And Submit
$form_state->setCached(FALSE);
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
// Return FORM
return $form;
}
/**
* Callback for both ajax-enabled buttons.
*
* Selects and returns the fieldset with the names in it.
*/
public function addmoreCallback(array &$form, FormStateInterface $form_state) {
return $form['names_fieldset'];
}
/**
* Submit handler for the "add-one-more" button.
*
* Increments the max counter and causes a rebuild.
*/
public function addOne(array &$form, FormStateInterface $form_state) {
// Store our form state
$field_deltas_array = $form_state->get('num_names');
// check to see if there is more than one item in our array
if (count($field_deltas_array) > 0) {
// Add a new element to our array and set it to our highest value plus one
$field_deltas_array[] = max($field_deltas_array) + 1;
}
else {
// Set the new array element to 0
$field_deltas_array[] = 0;
}
// Rebuild the field deltas values
$form_state->set('num_names', $field_deltas_array);
// Rebuild the form
$form_state->setRebuild();
}
/**
* Submit handler for the "remove this item" button.
*
* Search the triggering element and unset it
* Clean unset new array and rebuit it
*/
public function removeCallbackOne(array &$form, FormStateInterface $form_state) {
// Get the triggering item
$delta_remove = $form_state->getTriggeringElement()['#array_parents'][1];
// Store our form state
$field_deltas_array = $form_state->get('num_names');
// Find the key of the item we need to remove
$key_to_remove = array_search($delta_remove, $field_deltas_array);
// Remove our triggered element
unset($field_deltas_array[$key_to_remove]);
// return the reel array
foreach ($field_deltas_array as $key) {
$output[] = $key;
}
// // Rebuild the field deltas values
$form_state->set('num_names', $output);
// // Rebuild the form
$form_state->setRebuild();
}
/**
* Final submit handler.
*
* Reports what values were finally set.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Find output information
$name = $form_state->getValue(['names_fieldset', 'name']);
$forname = $form_state->getValue(['names_fieldset', 'forname']);
$identity = '';
// Gather the number of items returned by the form.
$num_names = $form_state->get('num_names')
// Process each items and format it
foreach ($num_names as $key) {
$name = $form_state->getValue(['names_fieldset', $key])['name'];
$forname = $form_state->getValue(['names_fieldset', $key])['forname'];
$identity .= $forname.' '.$name . ' ';
}
$identity = explode(' ', $identity);
// return the output
$output = t('These people are coming to the picnic: @names', [
'@names' => implode(', ', $identity),
]
);
drupal_set_message($output);
}
}