0

I am building a form using formBuilder. I have tried two methods to store values across form submit/validate for usage in ajax callbacks, but have been unsuccessful in either.

The first method, was to store a value in $form_state->set('name','value'); and retreiving it in the form submit/validate handler. That returned an empty result.

The second method was to store a variable on the class itself protected $image_deltas = 0; and then when the ajax form submit/validation is triggered, $this->image_deltas++; However, when I do this, it still does not work.

The following is the code I am using.

$form['images'] = [
  '#type' => 'container',
  '#id' => 'images',
];

dpm($this->image_deltas);

for ($i=0;$i<=$this->image_deltas;$i++) {
  $form['images'][$i]['image'] = [
    '#type' => 'textfield',
    '#title' => t('Image Path:'),
  ];
}

$form['add_another'] = [
  '#type' => 'button',
  '#value' => t('Add Another Image'),
  '#ajax' => [
    'callback' => [$this, 'addAnotherImage'],
    'wrapper' => 'images',
  ],
  '#submit' => [$this, 'addAnotherImageSubmit'],
  '#limit_validation_errors' => [],
];

The form submission handler is the following.

public function addAnotherImageSubmit(&$form, FormStateInterface $form_state) {
  $this->image_deltas++;
  $form_state->setRebuild();
}

The AJAX callback is the following one.

public function addAnotherImage(&$form, FormStateInterface $form_state) {
  return $form['images'];
}

When I submit the form, dpm() prints 0 every time. The same thing happens if I use $form_state->set('image_deltas') and $form_state->get('image_deltas').

1 Answer 1

1

This:

'#submit' => [$this, 'addAnotherImageSubmit'],

Should be this:

'#submit' => [[$this, 'addAnotherImageSubmit']],

Submit handlers are only called for #type submit and not #type button, so you'll need to change the type.

You will also need to use $form_state->set(), rather than a property on the class. This is because the form class is re-instantiated for each iteration (build, validate, submit), and therefore values stored in the properties of the form class will not persist. $form_state->set() persists values, as these are stored in the database, and are repopulated for each instance of the form class (as long as you call $form_state->setRebuild() as you have done).

12
  • Changing it to that has no difference. The form submits, and prints out the $this->image_deltas; as 0 still (which is default), instead of incrementing it like it should.
    – Ex0r
    Commented Feb 16, 2021 at 14:05
  • 1
    That's because the form class is re-instantiated for each iteration (build, validate, submit), and therefore values stored in the properties of the form class will not persist. You will need to use $form_state->set() to persist values, as these are stored in the database, and are repopulated for each instance of the form class.
    – Jaypan
    Commented Feb 16, 2021 at 17:25
  • As stated in the original question, I did that originally, and it was still not working as it's supposed to. $form_state->set() does not appear to persist across an ajax callback/request as I can set it inside of the submit/validate handler, and try to dump it into the form after ajax callback has ran, and the value returns empty.
    – Ex0r
    Commented Feb 16, 2021 at 17:56
  • 1
    It wouldn't work when you tried it earlier, as you had your submit handler declared incorrectly. You need to do both - declare your submit handler correctly, and use $form_state->set(). You didn't have your submit handler declared correctly, meaning your submit handler would not have been called, meaning $form_state->set() would never been called.
    – Jaypan
    Commented Feb 16, 2021 at 18:32
  • 1
    Submit handlers are not called for #type button. You need to change the type to submit.
    – Jaypan
    Commented Feb 16, 2021 at 19:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.