Voici comment dans un formulaire custom D8, avoir un ensemble de champ "multiples" dans un formulaire de config par exemple.
Dans mon exemple je n'ai que le champ « titre », mais c'est simplement pour alléger le snippet.
Le code en question :
config('monmodule.homepage');
$pomoted_items = $config->get('promoted', []);
$number_promoted = $form_state->getValue('number_promoted', count($pomoted_items));
$removed = $form_state->getValue('removed_promoted', []);
$form['number_promoted'] = [
'#type' => 'value',
'#value' => $number_promoted,
];
$form['removed'] = [
'#type' => 'value',
'#value' => $removed,
];
$form['promoted'] = [
'#type' => 'fieldset',
'#title' => t("À la une"),
'#tree' => TRUE,
];
for ($i = 1; $i 'fieldset',
'#title' => t("À la une #@i", ['@i' => $i]),
];
$form['promoted'][$i]['title'] = [
'#type' => 'textfield',
'#title' => $this->t("Titre"),
'#default_value' => $item['title'],
];
$form['promoted'][$i]['remove_' . $i] = array(
'#type' => 'submit',
'#value' => t("Supprimer l'élément #@i", ['@i' => $i]),
'#submit' => array('::removeItem'),
'#attributes' => [
'class' => ['button--danger'],
'data-toRemove' => $i,
]
);
}
$form['promoted']['add_item'] = array(
'#type' => 'submit',
'#value' => t('Ajouter un autre élément'),
'#submit' => array('::addPromotedItem'),
);
return parent::buildForm($form, $form_state);
}
public function addPromotedItem(array &$form, FormStateInterface $form_state) {
$form_state->setValue('number_promoted', $form_state->getValue('number_promoted') + 1);
$form_state->setRebuild();
}
public function removeItem(array &$form, FormStateInterface $form_state) {
$removed = $form_state->getValue('removed_promoted', []);
$removed[] = $form_state->getTriggeringElement()['#attributes']['data-toRemove'];
$form_state->setValue('removed_promoted', $removed);
$form_state->setRebuild();
}
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$parsed = [];
$promoted = $form_state->getValue('promoted');
foreach ($promoted as $promoted_item) {
if(is_array($promoted_item)) {
$parsed[] = $promoted_item;
}
}
$this->config('monmodule.homepage')->set('promoted', $parsed)->save();
}
}