1

I have a form with several ajax callback functions. And I have a variable which should change its value inside these callback functions. Unfortunately, I have faced with a problem. Namely, I don't know how to store the value of the variable after change. Because after the callback function executed the value is lost.

There is a little example of code.

class MyForm extends FormBase {
    public $i = 0;

public function buildForm(array $form, FormStateInterface $form_state){
    ...
    $form['add_more'] = [
        '#type' => 'submit',
        '#value' => 'Add More ...',
        '#ajax' => [
            'callback' => '::addMore',
        ]
    ];
    ...
}

public function addMore(array &$form, FormStateInterface $form_state){
    ...
    $this->i++;
    ...
}
}

Here the variable $i doesn't increase its value whenever the button is being pressed. Could you clarify, what should I do if I want the variable to increase its value whenever the button has been pressed ?

1

The ajax callback is not for form logic. It's only supposed to send back a new version of $form or part of it in a wrapper. Or in more advanced cases a collection of ajax commands.

Use instead buildForm(). You can check which button was clicked with $form_state->getTriggeringElement().

  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['#prefix'] = '<div id="ajax_wrapper">';
    $form['#suffix'] = '</div>';

    $i = $form_state->get('elem') ? $form_state->get('elem') : 1;
    $trigger = $form_state->getTriggeringElement();
    if (isset($trigger['#ajax']['callback']) && $trigger['#ajax']['callback'] === '::addMore') {
      $i++;
    }
    $form_state->set('elem', $i);

    $form['counter'] = [
      '#markup' => $form_state->get('elem') ?? 1,
    ];

    $form['btn'] = [
      '#type' => 'button',
      '#value' => 'Btn',
      '#ajax' => [
        'callback' => '::addMore',
        'wrapper' => 'ajax_wrapper',
      ]
    ];

    return $form;
  }

  public function addMore(array &$form, FormStateInterface $form_state){
    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state){

  }
8
  • I created a test form, but it doestn't work. Here is the code - slexy.org/view/s2NVttIMjM A field "counter" should display changing value of the iterator, but it doesn't do it. – Yakimkin Roman Aug 28 '17 at 5:51
  • You need to add a wrapper and some minor things (type button for ajax, get() instead of getValue()), then it works. I've modified your latest code example. – 4k4 Aug 28 '17 at 6:40
  • Your code didn't work, but I added into method submitForm the following content "$form_state->setRebuild();" and it has worked. – Yakimkin Roman Aug 28 '17 at 13:33
  • You don't need this for the example to work, but this is a good idea as fallback, if js is not available. – 4k4 Aug 28 '17 at 13:39
  • But if I doesn't return $form, but execute several Ajax operations in the callback function ? That is, I create an AjaxResponce object, next I add several different ajax commands into it, and I returns the object instead $form. Could you clarify me, what should i do in this case ? – Yakimkin Roman Aug 28 '17 at 15:27

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.