I'm using this form api example: AjaxAddMore. I want to add a "remove button" for each indiviaul element, in order to remove an item but not the latest. Thouse are my changes:

  $form['names_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('People coming to picnic'),
      '#prefix' => '<div id="names-fieldset-wrapper">',
      '#suffix' => '</div>',
      '#attributes' => array('class'=>array('container-inline')),

    for ($i = 0; $i < $num_names; $i++) {

      $form['names_fieldset']['fields'][$i] = [
        '#type' => 'fieldset',
        '#name' => 'id_'.$i

      $form['names_fieldset']['fields'][$i]['ids'] = [
        '#type' => 'textfield',
        '#title' => $this->t('ID'),
        '#default_value' => $i,
        '#name' => 'id_'.$i

      $form['names_fieldset']['fields'][$i]['name'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Name')

      $form['names_fieldset']['fields'][$i]['remove'] = [
        '#type' => 'submit',
        '#name' => 'remove_'.$i,
        '#value' => $this->t('Remove this'),
        '#submit' => ['::removethisCallback'],
        '#ajax' => [
          'callback' => '::addmoreCallback',
          'wrapper' => 'names-fieldset-wrapper',

It works good and I can add several records. But I can't remove an item other than the latest one. This is my callback function where I've tried to unset the item I want to remove:

public function removethisCallback(array &$form, FormStateInterface $form_state) {
    $button_clicked = $form_state->getTriggeringElement()['#name'];
    $id = substr($button_clicked,7);
    $values = $form_state->getValue(['names_fieldset']);
    $form_state->setValues(['names_fieldset'], array_values($values));  

    $name_field = $form_state->get('num_names');
    if ($name_field > 1) {
        $remove_button = $name_field - 1;
        $form_state->set('num_names', $remove_button);

But It doesn't work. How could I remove or update an item from $form_state?

  • unset($values[$id]); should be unset($values[$ids]) because your $form['names_fieldset']['fields'][$i]['ids'] has an "s". – No Sssweat Apr 20 at 10:14
  • Thanks for your answer, but I don't think so, because $id is a variable that hold the item index to delete. It isn't the field 'ids'. I get the item index to delete using $form_state->getTriggerElement, and then I get #name. – briast Apr 20 at 19:08
  • Ok then you don't need to unset, you just set a new value and that will override it. – No Sssweat Apr 20 at 23:36
  • Yes. That's what I want. But I don't find a way to do it. All changes I do over $form_state are lost. – briast Apr 21 at 9:25
  • try adding a & to $form_state in your function removethisCallback(array &$form, FormStateInterface &$form_state) { or try commenting out $form_state->setRebuild(); I don't think you need this. – No Sssweat Apr 21 at 10:23

$form_state->setValues(['names_fieldset'], array_values($values));

setValues(array $values) only has 1 parameter

For 2 params, you need to use setValue($key, $value) without the "s"

$form_state->setValue('name', array_values($values));  

Alternatively, you could do

$values = $form_state->getValues();
$values['name'] = array_values($values);

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.